GLAkavya commited on
Commit
f97d5c9
·
verified ·
1 Parent(s): 0f46b8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -18
app.py CHANGED
@@ -72,28 +72,41 @@ def ease_bounce(t):
72
  else: t-=2.625/2.75; return 7.5625*t*t+.984375
73
 
74
  def ken_burns(pil, duration_sec=6, fps=30, style="premium"):
75
- TW,TH=720,1280; pad=160; BW,BH=TW+pad*2,TH+pad*2
 
 
76
  total=duration_sec*fps
77
 
78
- # Prepare image
79
  img=pil.convert("RGB"); sw,sh=img.size
80
- if sw/sh>TW/TH: nw=int(sh*TW/TH); img=img.crop(((sw-nw)//2,0,(sw-nw)//2+nw,sh))
81
- else: nh=int(sw*TH/TW); img=img.crop((0,(sh-nh)//2,sw,(sh-nh)//2+nh))
82
- img=img.filter(ImageFilter.UnsharpMask(radius=1.0,percent=120,threshold=2))
83
- img=ImageEnhance.Contrast(img).enhance(1.06)
84
- img=ImageEnhance.Color(img).enhance(1.10)
85
- base=np.array(img.resize((BW,BH),Image.LANCZOS))
86
-
87
- # Pre-baked vignette mask (subtle)
 
 
 
 
 
 
 
 
 
 
88
  Y,X=np.ogrid[:TH,:TW]
89
  dist=np.sqrt(((X-TW/2)/(TW/2))**2+((Y-TH/2)/(TH/2))**2)
90
- vmask=np.clip(1.-0.28*np.maximum(dist-0.80,0)**2,0,1).astype(np.float32)
91
 
 
92
  SEG=[
93
- (0.00,0.25, 1.35,1.12, 0, -int(pad*.10), 0, -int(pad*.12)),
94
- (0.25,0.55, 1.12,1.07, -int(pad*.05),int(pad*.07),-int(pad*.12),-int(pad*.28)),
95
- (0.55,0.78, 1.07,1.04, int(pad*.07),int(pad*.16), -int(pad*.28),-int(pad*.16)),
96
- (0.78,1.00, 1.04,1.00, int(pad*.16),0, -int(pad*.16),0),
97
  ]
98
 
99
  tmp=tempfile.NamedTemporaryFile(suffix=".mp4",delete=False)
@@ -107,9 +120,7 @@ def ken_burns(pil, duration_sec=6, fps=30, style="premium"):
107
  te=ease_cubic((tg-t0)/(t1-t0))
108
  zoom=z0+(z1-z0)*te; pan_x=int(px0+(px1-px0)*te); pan_y=int(py0+(py1-py0)*te); break
109
  if zoom is None: zoom,pan_x,pan_y=1.,0,0
110
- if tg<0.20:
111
- s=(0.20-tg)/0.20*1.8
112
- pan_x+=int(s*math.sin(i*1.4)); pan_y+=int(s*math.cos(i*1.0))
113
 
114
  cw,ch=int(TW/zoom),int(TH/zoom)
115
  ox,oy=BW//2+pan_x,BH//2+pan_y
 
72
  else: t-=2.625/2.75; return 7.5625*t*t+.984375
73
 
74
  def ken_burns(pil, duration_sec=6, fps=30, style="premium"):
75
+ TW,TH=720,1280
76
+ # Small pad — just enough for gentle movement, no aggressive zoom
77
+ pad=60; BW,BH=TW+pad*2,TH+pad*2
78
  total=duration_sec*fps
79
 
80
+ # Prepare image — fit full image, letterbox if needed
81
  img=pil.convert("RGB"); sw,sh=img.size
82
+ # Fit entire image inside TH height, pad sides with blurred bg
83
+ scale=TH/sh; nw=int(sw*scale); nh=TH
84
+ if nw>TW: scale=TW/sw; nw=TW; nh=int(sh*scale)
85
+ img_resized=img.resize((nw,nh),Image.LANCZOS)
86
+ # Blurred background fill
87
+ bg=img.resize((TW,TH),Image.LANCZOS)
88
+ bg=bg.filter(ImageFilter.GaussianBlur(radius=20))
89
+ bg_arr=np.array(ImageEnhance.Brightness(bg).enhance(0.5))
90
+ canvas=Image.fromarray(bg_arr)
91
+ # Paste sharp image centered
92
+ px=(TW-nw)//2; py=(TH-nh)//2
93
+ canvas.paste(img_resized,(px,py))
94
+ canvas=canvas.filter(ImageFilter.UnsharpMask(radius=0.8,percent=110,threshold=2))
95
+ canvas=ImageEnhance.Contrast(canvas).enhance(1.05)
96
+ canvas=ImageEnhance.Color(canvas).enhance(1.08)
97
+ base=np.array(canvas.resize((BW,BH),Image.LANCZOS))
98
+
99
+ # Pre-baked vignette mask (very subtle)
100
  Y,X=np.ogrid[:TH,:TW]
101
  dist=np.sqrt(((X-TW/2)/(TW/2))**2+((Y-TH/2)/(TH/2))**2)
102
+ vmask=np.clip(1.-0.22*np.maximum(dist-0.85,0)**2,0,1).astype(np.float32)
103
 
104
+ # GENTLE zoom: 1.00→1.06 max — full image always visible
105
  SEG=[
106
+ (0.00,0.30, 1.00,1.04, 0, -int(pad*.40), 0, -int(pad*.40)),
107
+ (0.30,0.60, 1.04,1.06, -int(pad*.30), int(pad*.30), -int(pad*.40),-int(pad*.70)),
108
+ (0.60,0.80, 1.06,1.04, int(pad*.30), int(pad*.50), -int(pad*.70),-int(pad*.40)),
109
+ (0.80,1.00, 1.04,1.00, int(pad*.50), 0, -int(pad*.40), 0),
110
  ]
111
 
112
  tmp=tempfile.NamedTemporaryFile(suffix=".mp4",delete=False)
 
120
  te=ease_cubic((tg-t0)/(t1-t0))
121
  zoom=z0+(z1-z0)*te; pan_x=int(px0+(px1-px0)*te); pan_y=int(py0+(py1-py0)*te); break
122
  if zoom is None: zoom,pan_x,pan_y=1.,0,0
123
+ # No shake — keeps image stable and well-framed
 
 
124
 
125
  cw,ch=int(TW/zoom),int(TH/zoom)
126
  ox,oy=BW//2+pan_x,BH//2+pan_y