Skip to content

Instantly share code, notes, and snippets.

@me-suzy
Created April 22, 2025 05:56
Show Gist options
  • Save me-suzy/f38b9d4b5ccb4cd176e09590ae09178b to your computer and use it in GitHub Desktop.
Save me-suzy/f38b9d4b5ccb4cd176e09590ae09178b to your computer and use it in GitHub Desktop.
efect flaire.py
#!/usr/bin/env python3
import os
import numpy as np
from moviepy.editor import ImageClip, CompositeVideoClip, vfx
from PIL import Image
import cv2
# Calea imaginii și a fișierului de ieșire
IMAGE_PATH = r"d:\family-hugging.jpg"
OUTPUT_PATH = r"d:\family-hugging-animation.mp4"
# Durata animației (secunde)
DURATION = 10
def read_file_with_fallback_encoding(file_path):
"""Încearcă mai multe encodări pentru a citi un fișier text."""
encodings = ['utf-8', 'latin1', 'cp1252', 'iso-8859-1']
for encoding in encodings:
try:
with open(file_path, 'r', encoding=encoding):
return open(file_path, 'r', encoding=encoding).read()
except UnicodeDecodeError:
continue
print(f"Nu s-a putut citi fișierul {file_path}")
return None
def replace_special_chars(val):
"""Înlocuiește dash-uri tipografice cu minus simplu."""
return val.replace('–', '-').replace('—', '-')
def normalize_value(val):
"""Normalizează un șir: spații non-break, dash-uri speciale, strip+lower."""
if val is None:
return None
val = val.replace('\xa0', ' ')
val = replace_special_chars(val)
return val.strip().lower()
def apply_ken_burns_effect(clip, duration, zoom_factor=1.2):
"""Aplică efectul Ken Burns: zoom și panoramare sinusoidală."""
original_w, original_h = clip.size
def make_frame(t):
# calcul zoom
scale = 1 + (zoom_factor - 1) * (t / duration)
new_w, new_h = int(original_w * scale), int(original_h * scale)
# panoramare pe orizontală
max_shift = (new_w - original_w) / 2
x_shift = max_shift * np.sin((t / duration) * 2 * np.pi)
x_center = (new_w - original_w) / 2 - x_shift
y_center = (new_h - original_h) / 2
resized = clip.resize((new_w, new_h))
return resized.crop(
x_center=x_center,
y_center=y_center,
width=original_w,
height=original_h
).get_frame(t)
return clip.set_duration(duration).set_make_frame(make_frame)
def create_light_flare_effect(width, height, duration):
"""Creează un flare lumină care se mișcă și oscilează pe verticală."""
def flare_frame(t):
frame = np.zeros((height, width, 3), dtype=np.uint8)
fx = int(width * (t / duration))
fy = height // 2 + int(100 * np.sin((t * 2 * np.pi) / duration))
for y in range(height):
for x in range(width):
d = np.hypot(x - fx, y - fy)
if d < 150:
intensity = 255 * (1 - d / 150)
frame[y, x] = [int(intensity), int(intensity), 100]
return frame
clip = ImageClip(flare_frame(0), duration=duration)
clip = clip.set_make_frame(lambda t: flare_frame(t))
return clip.set_opacity(0.3)
def create_particles_effect(width, height, duration, num_particles=50):
"""Creează particule animate (scântei/petale) care urcă și oscilează."""
particles = []
for _ in range(num_particles):
x0 = np.random.randint(0, width)
y0 = np.random.randint(0, height)
pd = np.random.uniform(2, duration)
def make_particle_frame(t, x0=x0, y0=y0, pd=pd):
frame = np.zeros((height, width, 3), dtype=np.uint8)
if t < pd:
x = x0 + 50 * np.sin((t * 2 * np.pi) / pd)
y = y0 - t * 50
if 0 <= x < width and 0 <= y < height:
cv2.circle(frame, (int(x), int(y)), 2, (255, 255, 200), -1)
return frame
pclip = ImageClip(make_particle_frame(0), duration=duration)
pclip = pclip.set_make_frame(lambda t, f=make_particle_frame: f(t))
particles.append(pclip.set_opacity(0.7))
return particles
def create_color_shift_effect(clip, duration):
"""Aplică shift de luminozitate cadru cu cadru."""
def fl_brightness(get_frame, t):
frame = get_frame(t).astype(np.float32)
factor = 0.8 + 0.2 * np.sin((t / duration) * 2 * np.pi)
shifted = np.clip(frame * factor, 0, 255)
return shifted.astype('uint8')
return clip.fl(fl_brightness, apply_to=['video', 'mask'])
def create_color_tone_effect(clip, duration):
"""Aplică tranziție cald–rece pe tonurile de culoare."""
def make_frame(t):
frame = clip.get_frame(t).astype(np.float32)
f = np.sin((t / duration) * 2 * np.pi)
r_factor = 1 + 0.2 * f
b_factor = 1 - 0.2 * f
frame[:, :, 0] = np.clip(frame[:, :, 0] * r_factor, 0, 255)
frame[:, :, 2] = np.clip(frame[:, :, 2] * b_factor, 0, 255)
return frame.astype('uint8')
return clip.set_make_frame(make_frame)
def main():
print(f"Încarc imaginea: {IMAGE_PATH}")
image = Image.open(IMAGE_PATH)
width, height = image.size
print(f"Dimensiune imagine: {width}x{height}")
base = ImageClip(np.array(image), duration=DURATION)
print("Aplic efect Ken Burns...")
kb = apply_ken_burns_effect(base, DURATION)
print("Creez efect flare...")
flare = create_light_flare_effect(width, height, DURATION)
print("Creez particule...")
particles = create_particles_effect(width, height, DURATION)
print("Aplic efect shift de luminozitate...")
bright = create_color_shift_effect(kb, DURATION)
print("Aplic efect ton de culoare...")
toned = create_color_tone_effect(bright, DURATION)
print("Combin toate stratificările...")
clips = [toned, flare] + particles
final = CompositeVideoClip(clips)
print(f"Salvez animația în: {OUTPUT_PATH}")
final.write_videofile(
OUTPUT_PATH,
fps=24,
codec='libx264',
audio_codec='aac',
bitrate="2000k",
ffmpeg_params=["-crf", "23"]
)
final.close()
print("✅ Animația a fost creată cu succes!")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment