Spaces:
Running on Zero
Running on Zero
Upload app.py
Browse files
app.py
CHANGED
|
@@ -684,27 +684,18 @@ def _snap_canvas(aspect: float, current_canvas: str) -> str:
|
|
| 684 |
return fastest[ratio][0]
|
| 685 |
|
| 686 |
def _cover_crop(image_path: str, canvas_label: str) -> str:
|
| 687 |
-
"""
|
| 688 |
-
|
| 689 |
-
If aspect ratios differ, use a softly blurred, full-canvas version as the background and
|
| 690 |
-
place the entire original image, scaled to fit, in the center. This avoids hard bars and
|
| 691 |
-
preserves the original framing instead of center-cropping the person.
|
| 692 |
-
"""
|
| 693 |
-
from PIL import Image as _Image, ImageOps as _ImageOps, ImageFilter as _ImageFilter
|
| 694 |
|
| 695 |
h, w = CANVASES[canvas_label]
|
| 696 |
with _Image.open(image_path) as source:
|
| 697 |
-
img = source.convert("RGB")
|
| 698 |
-
if
|
| 699 |
return image_path
|
| 700 |
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
x = (w - foreground.width) // 2
|
| 705 |
-
y = (h - foreground.height) // 2
|
| 706 |
-
background.paste(foreground, (x, y))
|
| 707 |
-
background.save(image_path)
|
| 708 |
return image_path
|
| 709 |
|
| 710 |
def _fit_keyframe(image_path, current_canvas):
|
|
@@ -912,13 +903,10 @@ def generate(
|
|
| 912 |
corrected = path[:-4] + "-canvas.mp4"
|
| 913 |
subprocess.run(
|
| 914 |
[ffmpeg, "-y", "-i", path,
|
| 915 |
-
"-
|
| 916 |
-
f"
|
| 917 |
-
f"
|
| 918 |
-
|
| 919 |
-
f"[fg]scale={width}:{height}:force_original_aspect_ratio=decrease:flags=lanczos[fg];"
|
| 920 |
-
f"[bg][fg]overlay=(W-w)/2:(H-h)/2,setsar=1[v]",
|
| 921 |
-
"-map", "[v]", "-map", "0:a?",
|
| 922 |
"-c:v", "libx264", "-preset", "veryfast", "-crf", "18",
|
| 923 |
"-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart", corrected],
|
| 924 |
capture_output=True, text=True, check=True,
|
|
@@ -927,7 +915,7 @@ def generate(
|
|
| 927 |
resized = True
|
| 928 |
print(
|
| 929 |
f"[canvas] Model/encoder output {actual_width}x{actual_height}; "
|
| 930 |
-
f"final MP4
|
| 931 |
flush=True,
|
| 932 |
)
|
| 933 |
|
|
|
|
| 684 |
return fastest[ratio][0]
|
| 685 |
|
| 686 |
def _cover_crop(image_path: str, canvas_label: str) -> str:
|
| 687 |
+
"""Resize/crop the keyframe to fill the selected canvas, with no blurred background."""
|
| 688 |
+
from PIL import Image as _Image, ImageOps as _ImageOps
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
|
| 690 |
h, w = CANVASES[canvas_label]
|
| 691 |
with _Image.open(image_path) as source:
|
| 692 |
+
img = _ImageOps.exif_transpose(source).convert("RGB")
|
| 693 |
+
if img.size == (w, h):
|
| 694 |
return image_path
|
| 695 |
|
| 696 |
+
# Fill the complete canvas; if aspect ratios differ, crop excess edges.
|
| 697 |
+
fitted = _ImageOps.fit(img, (w, h), method=_Image.Resampling.LANCZOS)
|
| 698 |
+
fitted.save(image_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 699 |
return image_path
|
| 700 |
|
| 701 |
def _fit_keyframe(image_path, current_canvas):
|
|
|
|
| 903 |
corrected = path[:-4] + "-canvas.mp4"
|
| 904 |
subprocess.run(
|
| 905 |
[ffmpeg, "-y", "-i", path,
|
| 906 |
+
"-vf",
|
| 907 |
+
f"scale={width}:{height}:force_original_aspect_ratio=increase:flags=lanczos,"
|
| 908 |
+
f"crop={width}:{height},setsar=1",
|
| 909 |
+
"-map", "0:v:0", "-map", "0:a?",
|
|
|
|
|
|
|
|
|
|
| 910 |
"-c:v", "libx264", "-preset", "veryfast", "-crf", "18",
|
| 911 |
"-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart", corrected],
|
| 912 |
capture_output=True, text=True, check=True,
|
|
|
|
| 915 |
resized = True
|
| 916 |
print(
|
| 917 |
f"[canvas] Model/encoder output {actual_width}x{actual_height}; "
|
| 918 |
+
f"final MP4 filled to selected Canvas (excess edges cropped) {width}x{height}.",
|
| 919 |
flush=True,
|
| 920 |
)
|
| 921 |
|