media-converter / app.py
prasanthntu's picture
Update code, readme, and add gitignore
357f3f3
import gradio as gr
from PIL import Image
import os
import logging
from moviepy.video.io.VideoFileClip import VideoFileClip
import numpy as np
import tempfile
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler("image_converter.log"), logging.StreamHandler()],
)
logger = logging.getLogger(__name__)
def cleanup_temp_files():
"""Clean up temporary files"""
temp_files = ["input_image.png", "converted_image.webp"]
for file in temp_files:
if os.path.exists(file):
os.remove(file)
def get_image_stats(image_path, pil_image):
"""Get image file size (in KB) and dimensions"""
file_size_mb = os.path.getsize(image_path) / (1024)
width, height = pil_image.size
return f"Size: {file_size_mb:.0f}KB, Dimensions: {width}x{height}"
def convert_png_to_webp(image, quality=80):
if image is None:
logger.error("No image provided")
return None, None, "", ""
try:
cleanup_temp_files() # Clean up before conversion
# Save input image temporarily to get file size
input_path = "input_image.png"
image.save(input_path, "PNG")
input_stats = get_image_stats(input_path, image)
logger.info(
f"Starting conversion - Image size: {image.size}, Mode: {image.mode}"
)
# Convert image to WebP format
output_path = "converted_image.webp"
image = image.convert("RGBA") # Preserve transparency
image.save(output_path, "WEBP", quality=quality)
# Get output stats
output_image = Image.open(output_path)
output_stats = get_image_stats(output_path, output_image)
logger.info(f"Successfully converted image to WebP with quality {quality}")
return output_path, Image.open(output_path), input_stats, output_stats
except Exception as e:
logger.error(f"Error converting image: {str(e)}")
cleanup_temp_files()
return None, None, "", ""
def convert_video_to_webp(video_path, fps=10, quality=80):
if video_path is None:
logger.error("No video provided")
return None, None, ""
try:
# Load video and extract frames
video = VideoFileClip(video_path)
duration = video.duration
logger.info(f"Starting conversion - Duration: {duration:.1f}s, FPS: {fps}")
# Create temporary directory for frames
with tempfile.TemporaryDirectory() as temp_dir:
frames = []
for frame in video.iter_frames(fps=fps):
# Convert frame to PIL Image
pil_frame = Image.fromarray(frame)
frames.append(pil_frame)
# Save as animated WebP
output_path = "converted_animation.webp"
frames[0].save(
output_path,
save_all=True,
append_images=frames[1:],
duration=int(1000 / fps),
quality=quality,
method=6,
)
# Get stats
stats = f"Duration: {duration:.1f}s, Frames: {len(frames)}, FPS: {fps}"
video.close()
return output_path, Image.open(output_path), stats
except Exception as e:
logger.error(f"Error converting video: {str(e)}")
return None, None, ""
# Replace the Gradio Interface with Blocks
with gr.Blocks(title="Media Converter", theme=gr.themes.Soft()) as demo:
with gr.Tabs():
with gr.Tab("PNG to WebP"):
gr.Markdown(
"## PNG to WebP Converter\nUpload a PNG image and convert it to WebP format with adjustable quality."
)
with gr.Row():
with gr.Column(scale=1):
input_image = gr.Image(type="pil", label="Upload PNG Image")
quality = gr.Slider(10, 100, value=80, step=5, label="Quality")
with gr.Column(scale=1):
output_file = gr.File(label="Download WebP Image")
output_preview = gr.Image(label="Preview")
input_stats = gr.Textbox(label="Input Image Details")
output_stats = gr.Textbox(label="Output Image Details")
# Set up event listeners for automatic conversion
input_image.change(
fn=convert_png_to_webp,
inputs=[input_image, quality],
outputs=[output_file, output_preview, input_stats, output_stats],
)
quality.change(
fn=convert_png_to_webp,
inputs=[input_image, quality],
outputs=[output_file, output_preview, input_stats, output_stats],
)
with gr.Tab("Video to WebP"):
with gr.Row():
with gr.Column(scale=1):
input_video = gr.Video(label="Upload MOV Video")
with gr.Row():
fps = gr.Slider(1, 30, value=10, step=1, label="FPS")
quality = gr.Slider(10, 100, value=80, step=5, label="Quality")
with gr.Column(scale=1):
output_file = gr.File(label="Download WebP Animation")
output_preview = gr.Image(label="Preview")
video_stats = gr.Textbox(label="Video Details")
# Set up event listeners for video conversion
input_video.change(
fn=convert_video_to_webp,
inputs=[input_video, fps, quality],
outputs=[output_file, output_preview, video_stats],
)
with gr.Tab("README"):
with gr.Column(scale=1):
gr.Markdown(
"""### ⓘ Note:
The converter works both locally and in remote.<br>
For more details (source codes, clone repo, etc.), visit [README](https://huggingface.co/spaces/prasanthntu/media-converter/blob/main/README.md)""",
label="Note",
show_label=True,
container=True,
)
if __name__ == "__main__":
demo.launch()