broadfield-dev commited on
Commit
4bc0c43
·
verified ·
1 Parent(s): b22ed9b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image
3
+ import os
4
+ from io import BytesIO
5
+
6
+ def get_gif_info(gif_file):
7
+ """Get GIF dimensions and frame count."""
8
+ try:
9
+ with Image.open(gif_file) as img:
10
+ width, height = img.size
11
+ frames = 0
12
+ try:
13
+ while True:
14
+ img.seek(img.tell() + 1)
15
+ frames += 1
16
+ except EOFError:
17
+ img.seek(0) # Reset to first frame
18
+ return width, height, frames + 1
19
+ except Exception as e:
20
+ return None, None, None, f"Error: {str(e)}"
21
+
22
+ def resize_gif(gif_file, width, height, lock_ratio):
23
+ """Resize GIF while maintaining quality and aspect ratio."""
24
+ try:
25
+ # Open the GIF
26
+ with Image.open(gif_file) as img:
27
+ original_width, original_height = img.size
28
+ frames = []
29
+
30
+ # If lock_ratio is enabled, calculate height based on width
31
+ if lock_ratio and width:
32
+ height = int((width / original_width) * original_height)
33
+
34
+ if not width or not height:
35
+ return None, "Please provide valid width and/or height"
36
+
37
+ # Process each frame
38
+ try:
39
+ while True:
40
+ # Convert frame to RGB if needed
41
+ frame = img.convert('RGBA')
42
+ # Resize frame using LANCZOS for better quality
43
+ resized_frame = frame.resize((int(width), int(height)), Image.LANCZOS)
44
+ frames.append(resized_frame)
45
+ img.seek(img.tell() + 1)
46
+ except EOFError:
47
+ pass
48
+
49
+ # Create output BytesIO object
50
+ output = BytesIO()
51
+
52
+ # Save the resized GIF
53
+ frames[0].save(
54
+ output,
55
+ format='GIF',
56
+ save_all=True,
57
+ append_images=frames[1:],
58
+ loop=0,
59
+ duration=img.info.get('duration', 100),
60
+ optimize=True,
61
+ quality=95
62
+ )
63
+
64
+ # Get new file size
65
+ new_size = len(output.getvalue()) / 1024 # Size in KB
66
+
67
+ # Reset BytesIO cursor and return
68
+ output.seek(0)
69
+ return output, f"Original Size: {original_width}x{original_height}\nNew Size: {width}x{height}\nFile Size: {new_size:.2f} KB"
70
+
71
+ except Exception as e:
72
+ return None, f"Error processing GIF: {str(e)}"
73
+
74
+ def update_height(width, original_width, original_height, lock_ratio):
75
+ """Update height input when aspect ratio is locked."""
76
+ if lock_ratio and width and original_width and original_height:
77
+ try:
78
+ return int((int(width) / original_width) * original_height)
79
+ except:
80
+ return None
81
+ return None
82
+
83
+ def process_gif(gif_file, width, height, lock_ratio):
84
+ """Main function to process the uploaded GIF."""
85
+ if not gif_file:
86
+ return None, "Please upload a GIF file", None
87
+
88
+ # Get GIF info
89
+ original_width, original_height, frame_count, error = get_gif_info(gif_file)
90
+
91
+ if error:
92
+ return None, error, None
93
+
94
+ # Resize GIF
95
+ output, message = resize_gif(gif_file, width, height, lock_ratio)
96
+
97
+ return output, f"GIF Info:\nWidth: {original_width}px\nHeight: {original_height}px\nFrames: {frame_count}\n\n{message}", output
98
+
99
+ # Gradio Interface
100
+ with gr.Blocks() as demo:
101
+ gr.Markdown("# GIF Resizer")
102
+ gr.Markdown("Upload a GIF, set the desired dimensions, and download the resized version.")
103
+
104
+ with gr.Row():
105
+ with gr.Column():
106
+ gif_input = gr.File(label="Upload GIF", file_types=[".gif"])
107
+ lock_ratio = gr.Checkbox(label="Lock Aspect Ratio", value=True)
108
+
109
+ with gr.Row():
110
+ width_input = gr.Number(label="Width (px)", value=None)
111
+ height_input = gr.Number(label="Height (px)", value=None)
112
+
113
+ resize_button = gr.Button("Resize GIF")
114
+
115
+ with gr.Column():
116
+ output_info = gr.Textbox(label="GIF Information")
117
+ output_gif = gr.Image(label="Resized GIF", type="filepath")
118
+ download_button = gr.File(label="Download Resized GIF")
119
+
120
+ # Event handlers
121
+ gif_input.change(
122
+ fn=get_gif_info,
123
+ inputs=gif_input,
124
+ outputs=[width_input, height_input, output_info]
125
+ )
126
+
127
+ width_input.change(
128
+ fn=update_height,
129
+ inputs=[width_input, width_input, height_input, lock_ratio],
130
+ outputs=height_input
131
+ )
132
+
133
+ resize_button.click(
134
+ fn=process_gif,
135
+ inputs=[gif_input, width_input, height_input, lock_ratio],
136
+ outputs=[output_gif, output_info, download_button]
137
+ )
138
+
139
+ demo.launch()