Skip to content

Instantly share code, notes, and snippets.

@me-suzy
Created April 22, 2025 05:58
Show Gist options
  • Save me-suzy/e86bd47aa730cb70fd85386cec026b55 to your computer and use it in GitHub Desktop.
Save me-suzy/e86bd47aa730cb70fd85386cec026b55 to your computer and use it in GitHub Desktop.
Efect Flaire 2.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
IMAGE_PATH = r"d:\family-hugging.jpg"
OUTPUT_PATH = r"d:\family-hugging-animation.mp4"
# Durata animației
DURATION = 10 # 10 secunde
def apply_ken_burns_effect(clip, duration, zoom_factor=1.2):
"""Aplică efectul Ken Burns: zoom și panoramare simulată"""
print("Aplic efect Ken Burns...")
width, height = clip.size
original_w, original_h = clip.size
def make_frame(t):
# Zoom progresiv
scale = 1 + (zoom_factor - 1) * (t / duration)
new_w, new_h = int(original_w * scale), int(original_h * scale)
# Calculăm poziția pentru panoramare (stânga-dreapta)
max_shift = (new_w - original_w) / 2
x_shift = max_shift * np.sin((t / duration) * 2 * np.pi) # Mișcare sinusoidală
x_center = (new_w - original_w) / 2 - x_shift
y_center = (new_h - original_h) / 2
# Redimensionăm și decupăm imaginea pentru a simula zoom și panoramare
resized = clip.resize((new_w, new_h))
cropped = resized.crop(
x_center=x_center,
y_center=y_center,
width=original_w,
height=original_h
)
return cropped.get_frame(t)
# Creăm un clip nou cu cadrele generate
return clip.set_duration(duration).set_make_frame(make_frame)
def create_light_flare_effect(width, height, duration):
"""Creează un efect de lumină care se mișcă peste imagine"""
print("Creez efect de lumină...")
def flare_frame(t):
frame = np.zeros((height, width, 3), dtype=np.uint8)
flare_center_x = int(width * (t / duration))
flare_center_y = height // 2 + int(100 * np.sin((t * 2 * np.pi) / duration))
for y in range(height):
for x in range(width):
distance = np.sqrt((x - flare_center_x)**2 + (y - flare_center_y)**2)
if distance < 150:
intensity = 255 * (1 - distance / 150)
frame[y, x] = [int(intensity), int(intensity), 100]
return frame
flare_clip = ImageClip(flare_frame(0), duration=duration)
flare_clip = flare_clip.set_make_frame(lambda t: flare_frame(t))
return flare_clip.set_opacity(0.3)
def create_particles_effect(width, height, duration, num_particles=50):
"""Creează particule animate (scântei sau petale)"""
print("Creez efect de particule...")
particles = []
for _ in range(num_particles):
x = np.random.randint(0, width)
y = np.random.randint(0, height)
particle_duration = np.random.uniform(2, duration)
speed = np.random.uniform(30, 70)
# Captăm valorile în closure
x_start, y_start = x, y
p_duration, p_speed = particle_duration, speed
def make_particle_frame(t, x=x_start, y=y_start,
particle_duration=p_duration, speed=p_speed):
frame = np.zeros((height, width, 3), dtype=np.uint8)
if t < particle_duration:
x_pos = x + 50 * np.sin((t * 2 * np.pi) / particle_duration)
y_pos = y - t * speed
if 0 <= y_pos < height and 0 <= x_pos < width:
cv2.circle(frame, (int(x_pos), int(y_pos)), 2, (255, 255, 200), -1)
return frame
particle = ImageClip(make_particle_frame(0), duration=duration)
particle = particle.set_make_frame(lambda t: make_particle_frame(t))
particles.append(particle.set_opacity(0.7))
return particles
def create_color_shift_effect(clip, duration):
"""Aplică o tranziție subtilă de luminozitate"""
print("Aplic efect de tranziție de luminozitate...")
def make_frame(t):
# Obținem cadrul curent
frame = clip.get_frame(t)
# Calculăm factorul de luminozitate
factor = 0.8 + 0.2 * np.sin((t / duration) * 2 * np.pi) # Variază între 0.8 și 1.0
# Aplicăm factorul direct și asigurăm că valorile rămân între 0-255
return np.clip(frame * factor, 0, 255).astype('uint8')
# Creăm un clip nou cu funcția de transformare
return clip.fl_image(lambda img: make_frame(clip.to_seconds(img)))
def create_color_tone_effect(clip, duration):
"""Aplică o tranziție de tonuri de culoare (cald-rece)"""
print("Aplic efect de tranziție de tonuri de culoare...")
def tone_transform(get_frame, t):
frame = get_frame(t)
factor = np.sin((t / duration) * 2 * np.pi)
# Ajustăm canalele RGB pentru a simula tranziția cald-rece
r_factor = 1 + 0.2 * factor # Accentuăm roșul pentru tonuri calde
b_factor = 1 - 0.2 * factor # Accentuăm albastrul pentru tonuri reci
new_frame = frame.copy()
new_frame[:, :, 0] = np.clip(frame[:, :, 0] * r_factor, 0, 255) # Canalul R
new_frame[:, :, 2] = np.clip(frame[:, :, 2] * b_factor, 0, 255) # Canalul B
return new_frame
return clip.fl(tone_transform)
def main():
print(f"Încarc imaginea: {IMAGE_PATH}")
try:
image = Image.open(IMAGE_PATH)
width, height = image.size
print(f"Dimensiune imagine: {width}x{height}")
base_clip = ImageClip(np.array(image), duration=DURATION)
print("Imaginea a fost convertită în clip video")
# Aplicăm efectul Ken Burns
ken_burns_clip = apply_ken_burns_effect(base_clip, DURATION)
# Creăm efectul de lumină
flare_clip = create_light_flare_effect(width, height, DURATION)
# Creăm particulele
particle_clips = create_particles_effect(width, height, DURATION)
# Aplicăm efectul de luminozitate
enhanced_clip = create_color_shift_effect(ken_burns_clip, DURATION)
# Aplicăm efectul de tonuri de culoare
final_base_clip = create_color_tone_effect(enhanced_clip, DURATION)
print("Combin efectele...")
all_clips = [final_base_clip, flare_clip] + particle_clips
final_video = CompositeVideoClip(all_clips)
print(f"Salvez animația: {OUTPUT_PATH}")
final_video.write_videofile(
OUTPUT_PATH,
fps=24,
codec='libx264',
audio_codec='aac',
bitrate="2000k",
ffmpeg_params=["-crf", "23"],
threads=4
)
print("\n✅ Animația a fost creată cu succes!")
except Exception as e:
print(f"❌ Eroare: {str(e)}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment