Spaces:
Running on Zero
Running on Zero
File size: 3,924 Bytes
cdefade | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import io
import urllib.request
import cv2
import numpy as np
from PIL import Image
from config import (
MAX_DIM, MIN_DIM, SQUARE_DIM, MULTIPLE_OF,
FIXED_FPS, MIN_FRAMES_MODEL, MAX_FRAMES_MODEL
)
def load_image_from_url(url: str) -> Image.Image:
if not url or not str(url).strip():
raise ValueError("Masukkan URL gambar terlebih dahulu.")
url = str(url).strip()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req, timeout=15) as resp:
img_bytes = resp.read()
img = Image.open(io.BytesIO(img_bytes))
return img.convert("RGB")
get_timestamp_js = """
function(video, timestamp) {
const videoElem = document.querySelector('#generated-video video');
let currentTime = 0;
if (videoElem) {
currentTime = videoElem.currentTime;
console.log("Video found! Time: " + currentTime);
} else {
console.log("No video element found.");
}
return [video, currentTime];
}
"""
def extract_frame(video_path, timestamp):
if not video_path:
return None, 0
print(f"Extracting frame at timestamp: {timestamp}")
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
return None, timestamp
fps = cap.get(cv2.CAP_PROP_FPS)
if fps <= 0:
fps = 16.0
target_frame_num = int(float(timestamp) * fps)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
if total_frames > 0 and target_frame_num >= total_frames:
target_frame_num = total_frames - 1
cap.set(cv2.CAP_PROP_POS_FRAMES, target_frame_num)
ret, frame = cap.read()
cap.release()
if ret:
return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), timestamp
return None, timestamp
def resize_image(image: Image.Image) -> Image.Image:
width, height = image.size
if width == height:
return image.resize((SQUARE_DIM, SQUARE_DIM), Image.LANCZOS)
aspect_ratio = width / height
MAX_ASPECT_RATIO = MAX_DIM / MIN_DIM
MIN_ASPECT_RATIO = MIN_DIM / MAX_DIM
image_to_resize = image
if aspect_ratio > MAX_ASPECT_RATIO:
target_w, target_h = MAX_DIM, MIN_DIM
crop_width = int(round(height * MAX_ASPECT_RATIO))
left = (width - crop_width) // 2
image_to_resize = image.crop((left, 0, left + crop_width, height))
elif aspect_ratio < MIN_ASPECT_RATIO:
target_w, target_h = MIN_DIM, MAX_DIM
crop_height = int(round(width / MIN_ASPECT_RATIO))
top = (height - crop_height) // 2
image_to_resize = image.crop((0, top, width, top + crop_height))
else:
if width > height:
target_w = MAX_DIM
target_h = int(round(target_w / aspect_ratio))
else:
target_h = MAX_DIM
target_w = int(round(target_h * aspect_ratio))
final_w = round(target_w / MULTIPLE_OF) * MULTIPLE_OF
final_h = round(target_h / MULTIPLE_OF) * MULTIPLE_OF
final_w = max(MIN_DIM, min(MAX_DIM, final_w))
final_h = max(MIN_DIM, min(MAX_DIM, final_h))
return image_to_resize.resize((final_w, final_h), Image.LANCZOS)
def resize_and_crop_to_match(target_image, reference_image):
ref_width, ref_height = reference_image.size
target_width, target_height = target_image.size
scale = max(ref_width / target_width, ref_height / target_height)
new_width, new_height = int(target_width * scale), int(target_height * scale)
resized = target_image.resize((new_width, new_height), Image.Resampling.LANCZOS)
left, top = (new_width - ref_width) // 2, (new_height - ref_height) // 2
return resized.crop((left, top, left + ref_width, top + ref_height))
def get_num_frames(duration_seconds: float):
raw = int(round(duration_seconds * FIXED_FPS))
raw = max(MIN_FRAMES_MODEL, min(MAX_FRAMES_MODEL, raw))
return ((raw - 1) // 4) * 4 + 1
|