Spaces:
Sleeping
Sleeping
File size: 4,854 Bytes
4bc0c43 98cdf49 4bc0c43 155db1c 4bc0c43 155db1c 4bc0c43 |
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import gradio as gr
from PIL import Image
import os
from io import BytesIO
def get_gif_info(gif_file):
"""Get GIF dimensions and frame count."""
try:
with Image.open(gif_file) as img:
width, height = img.size
frames = 0
try:
while True:
img.seek(img.tell() + 1)
frames += 1
except EOFError:
img.seek(0) # Reset to first frame
return width, height, frames + 1, "Success"
except Exception as e:
return None, None, None, f"Error: {str(e)}"
def resize_gif(gif_file, width, height, lock_ratio):
"""Resize GIF while maintaining quality and aspect ratio."""
try:
# Open the GIF
with Image.open(gif_file) as img:
original_width, original_height = img.size
frames = []
# If lock_ratio is enabled, calculate height based on width
if lock_ratio and width:
height = int((width / original_width) * original_height)
if not width or not height:
return None, "Please provide valid width and/or height"
# Process each frame
try:
while True:
# Convert frame to RGB if needed
frame = img.convert('RGBA')
# Resize frame using LANCZOS for better quality
resized_frame = frame.resize((int(width), int(height)), Image.LANCZOS)
frames.append(resized_frame)
img.seek(img.tell() + 1)
except EOFError:
pass
# Create output BytesIO object
output = BytesIO()
# Save the resized GIF
frames[0].save(
output,
format='GIF',
save_all=True,
append_images=frames[1:],
loop=0,
duration=img.info.get('duration', 100),
optimize=True,
quality=95
)
# Get new file size
new_size = len(output.getvalue()) / 1024 # Size in KB
# Reset BytesIO cursor and return
output.seek(0)
return output, f"Original Size: {original_width}x{original_height}\nNew Size: {width}x{height}\nFile Size: {new_size:.2f} KB"
except Exception as e:
return None, f"Error processing GIF: {str(e)}"
def update_height(width, original_width, original_height, lock_ratio):
"""Update height input when aspect ratio is locked."""
if lock_ratio and width and original_width and original_height:
try:
return int((int(width) / original_width) * original_height)
except:
return None
return None
def process_gif(gif_file, width, height, lock_ratio):
"""Main function to process the uploaded GIF."""
if not gif_file:
return None, "Please upload a GIF file", None
# Get GIF info
original_width, original_height, frame_count, error = get_gif_info(gif_file)
if error:
return None, error, None
# Resize GIF
output, message = resize_gif(gif_file, width, height, lock_ratio)
return output, f"GIF Info:\nWidth: {original_width}px\nHeight: {original_height}px\nFrames: {frame_count}\n\n{message}", output
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("# GIF Resizer")
gr.Markdown("Upload a GIF, set the desired dimensions, and download the resized version.")
msg = gr.Markdown()
with gr.Row():
with gr.Column():
gif_input = gr.File(label="Upload GIF", file_types=[".gif"])
lock_ratio = gr.Checkbox(label="Lock Aspect Ratio", value=True)
with gr.Row():
width_input = gr.Number(label="Width (px)", value=None)
height_input = gr.Number(label="Height (px)", value=None)
resize_button = gr.Button("Resize GIF")
with gr.Column():
output_info = gr.Textbox(label="GIF Information")
output_gif = gr.Image(label="Resized GIF", type="filepath")
download_button = gr.File(label="Download Resized GIF")
# Event handlers
gif_input.change(
fn=get_gif_info,
inputs=gif_input,
outputs=[width_input, height_input, output_info, msg]
)
width_input.change(
fn=update_height,
inputs=[width_input, width_input, height_input, lock_ratio],
outputs=height_input
)
resize_button.click(
fn=process_gif,
inputs=[gif_input, width_input, height_input, lock_ratio],
outputs=[output_gif, output_info, download_button]
)
demo.launch() |