Mudrock10's picture
Update app.py from anycoder
92d2cce verified
<|begin_of_box|>import gradio as gr
import numpy as np
import cv2
import tempfile
import os
from PIL import Image
import time
# Simulated outpainting function (in a real application, this would use a proper model)
def outpaint_video_with_reference(input_video, reference_image, outpaint_ratio=0.5):
"""
Simulate video outpainting to match reference image height.
In a real implementation, this would use a diffusion model or similar.
"""
try:
# Create temporary files for processing
with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as temp_video:
temp_video_path = temp_video.name
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as temp_ref:
temp_ref_path = temp_ref.name
# Save uploaded files
with open(input_video, 'wb') as f:
f.write(open(input_video, 'rb').read())
with open(reference_image, 'wb') as f:
f.write(open(reference_image, 'rb').read())
# Get video and reference image dimensions
cap = cv2.VideoCapture(input_video)
ref_img = Image.open(reference_image)
ref_height = ref_img.height
ref_width = ref_img.width
# Get original video dimensions
original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# Calculate new dimensions to match reference height
new_height = ref_height
scale_factor = new_height / original_height
new_width = int(original_width * scale_factor)
# Create output video writer
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(temp_video_path, fourcc, 30.0, (new_width, new_height))
frame_count = 0
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Resize frame to match new dimensions
resized_frame = cv2.resize(frame, (new_width, new_height))
# Simulate outpainting by adding a border that matches reference style
# In a real implementation, this would use AI to generate content
border_size = int(new_width * outpaint_ratio)
if border_size > 0:
# Create a border that tries to match the reference image style
border_color = np.mean(resized_frame, axis=(0, 1))
bordered_frame = cv2.copyMakeBorder(
resized_frame,
0, 0, border_size, border_size,
cv2.BORDER_CONSTANT,
value=border_color
)
out.write(bordered_frame)
else:
out.write(resized_frame)
frame_count += 1
if frame_count % 10 == 0:
yield f"Processing frame {frame_count}/{total_frames}..."
cap.release()
out.release()
# Return the processed video
yield temp_video_path
except Exception as e:
yield f"Error: {str(e)}"
finally:
# Clean up temporary files
try:
if 'temp_video_path' in locals() and os.path.exists(temp_video_path):
os.unlink(temp_video_path)
if 'temp_ref_path' in locals() and os.path.exists(temp_ref_path):
os.unlink(temp_ref_path)
except:
pass
# Create the Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# 🎬 Video Outpainting with Reference Height Matching")
gr.Markdown("Upload a video and a reference image. The video will be outpainted to match the height of the reference image.")
with gr.Row():
with gr.Column():
gr.Markdown("### Input Video")
video_input = gr.Video(label="Upload Video", type="filepath")
gr.Markdown("### Reference Image")
reference_input = gr.Image(label="Upload Reference Image", type="filepath")
outpaint_ratio = gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.3,
step=0.1,
label="Outpaint Ratio (percentage of new width)"
)
process_button = gr.Button("Process Video", variant="primary")
with gr.Column():
gr.Markdown("### Output")
output_video = gr.Video(label="Processed Video")
status_text = gr.Textbox(label="Status", interactive=False)
# Process function
def process_video(video, reference, ratio):
if not video or not reference:
return None, "Please upload both video and reference image"
status_text = ""
for status in outpaint_video_with_reference(video, reference, ratio):
if isinstance(status, str):
status_text = status
yield None, status_text
else:
yield status, "Processing complete!"
process_button.click(
fn=process_video,
inputs=[video_input, reference_input, outpaint_ratio],
outputs=[output_video, status_text],
api_visibility="public"
)
# Launch the app with modern theme
demo.launch(
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="indigo",
neutral_hue="slate",
font=gr.themes.GoogleFont("Inter"),
text_size="lg",
spacing_size="lg",
radius_size="md"
).set(
button_primary_background_fill="*primary_600",
button_primary_background_fill_hover="*primary_700",
block_title_text_weight="600",
),
footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}]
)<|end_of_box|>