Jeffgold commited on
Commit
1c46be0
·
verified ·
1 Parent(s): b034888

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -113
app.py CHANGED
@@ -1,142 +1,71 @@
1
  import gradio as gr
2
- from PIL import Image, ImageDraw
3
  import io
4
- from math import cos, radians, sin
5
- import numpy as np
6
 
7
- def create_gif(img1, img2, transition_type):
 
 
 
 
 
 
 
8
  frames = []
9
  duration = 100 # Duration for each frame in milliseconds
10
  total_frames = 18 # Total number of frames
11
 
12
- try:
13
- # Set size for the GIF
14
- size = (256, 256)
15
- img1 = Image.fromarray(img1).convert('RGBA').resize(size, Image.LANCZOS)
16
- img2 = Image.fromarray(img2).convert('RGBA').resize(size, Image.LANCZOS)
17
-
18
- if transition_type == "default":
19
- # Default sliding transition
20
- full_width = size[0]
21
- step = full_width // (total_frames // 2)
22
-
23
- for i in range(0, full_width, step):
24
- frame = Image.new('RGBA', size)
25
- frame.paste(img1, (0, 0))
26
- frame.paste(img2.crop((i, 0, full_width, size[1])), (i, 0), mask=img2.crop((i, 0, full_width, size[1])))
27
- draw = ImageDraw.Draw(frame)
28
- draw.line((i, 0, i, size[1]), fill=(0, 255, 0), width=2)
29
- frame = frame.convert('P', palette=Image.ADAPTIVE)
30
- frames.append(frame)
31
-
32
- for i in range(full_width, step, -step):
33
- frame = Image.new('RGBA', size)
34
- frame.paste(img1, (0, 0))
35
- frame.paste(img2.crop((i, 0, full_width, size[1])), (i, 0), mask=img2.crop((i, 0, full_width, size[1])))
36
- draw = ImageDraw.Draw(frame)
37
- draw.line((i, 0, i, size[1]), fill=(0, 255, 0), width=2)
38
- frame = frame.convert('P', palette=Image.ADAPTIVE)
39
- frames.append(frame)
40
-
41
- elif transition_type == "rotate":
42
- # Rotating transition
43
- mask_size = (size[0] * 2, size[1] * 2)
44
- mask = Image.new('L', mask_size, 0)
45
- draw = ImageDraw.Draw(mask)
46
- draw.rectangle([size[0], 0, mask_size[0], mask_size[1]], fill=255)
47
-
48
- center_x, center_y = size[0] // 2, size[1] // 2
49
-
50
- for angle in range(0, 360, 360 // total_frames):
51
- rotated_mask = mask.rotate(angle, center=(mask_size[0] // 2, mask_size[1] // 2), expand=False)
52
- cropped_mask = rotated_mask.crop((size[0] // 2, size[1] // 2, size[0] // 2 + size[0], size[1] // 2 + size[1]))
53
- frame = Image.composite(img1, img2, cropped_mask)
54
-
55
- draw = ImageDraw.Draw(frame)
56
- reverse_angle = -angle + 90
57
- end_x1 = center_x + int(size[0] * 1.5 * cos(radians(reverse_angle)))
58
- end_y1 = center_y + int(size[1] * 1.5 * sin(radians(reverse_angle)))
59
- end_x2 = center_x - int(size[0] * 1.5 * cos(radians(reverse_angle)))
60
- end_y2 = center_y - int(size[1] * 1.5 * sin(radians(reverse_angle)))
61
- draw.line([center_x, center_y, end_x1, end_y1], fill=(0, 255, 0), width=3)
62
- draw.line([center_x, center_y, end_x2, end_y2], fill=(0, 255, 0), width=3)
63
 
64
- frame = frame.convert('P', palette=Image.ADAPTIVE)
65
- frames.append(frame)
 
 
 
 
66
 
67
- # Save as GIF
68
- output = io.BytesIO()
69
- frames[0].save(output, format='GIF', save_all=True, append_images=frames[1:], duration=duration, loop=0, optimize=True)
70
- output.seek(0)
 
71
 
72
- return output.getvalue()
73
- except Exception as e:
74
- raise ValueError(f"Error creating GIF: {e}")
 
75
 
76
- def create_gif_gradio(image1, image2, transition_type):
77
- gif_data = create_gif(image1, image2, transition_type)
78
-
79
  # Save the GIF to a temporary file
80
  temp_output_path = "output.gif"
81
  with open(temp_output_path, "wb") as f:
82
- f.write(gif_data)
83
 
84
  return temp_output_path
85
 
86
- def crop_image(image, top, left, bottom, right):
87
- if image is None:
88
- return None
89
- h, w = image.shape[:2]
90
- return image[int(top*h):int((1-bottom)*h), int(left*w):int((1-right)*w)]
91
-
92
  # Gradio interface
93
  with gr.Blocks() as iface:
94
- gr.Markdown("# GIF Generator with Image Cropping")
95
 
96
  with gr.Row():
97
- with gr.Column():
98
- image1 = gr.Image(label="Image 1")
99
- top1 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Top")
100
- left1 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Left")
101
- bottom1 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Bottom")
102
- right1 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Right")
103
- preview1 = gr.Image(label="Preview 1")
104
-
105
- with gr.Column():
106
- image2 = gr.Image(label="Image 2")
107
- top2 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Top")
108
- left2 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Left")
109
- bottom2 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Bottom")
110
- right2 = gr.Slider(0, 0.5, value=0, step=0.01, label="Crop Right")
111
- preview2 = gr.Image(label="Preview 2")
112
-
113
- transition_type = gr.Radio(["default", "rotate"], label="Transition Type", value="default")
114
 
115
  generate_button = gr.Button("Generate GIF")
116
  output_gif = gr.Image(type="filepath", label="Generated GIF")
117
 
118
- def update_preview1(image, top, left, bottom, right):
119
- return crop_image(image, top, left, bottom, right)
120
-
121
- def update_preview2(image, top, left, bottom, right):
122
- return crop_image(image, top, left, bottom, right)
123
-
124
- image1.change(update_preview1, inputs=[image1, top1, left1, bottom1, right1], outputs=preview1)
125
- top1.change(update_preview1, inputs=[image1, top1, left1, bottom1, right1], outputs=preview1)
126
- left1.change(update_preview1, inputs=[image1, top1, left1, bottom1, right1], outputs=preview1)
127
- bottom1.change(update_preview1, inputs=[image1, top1, left1, bottom1, right1], outputs=preview1)
128
- right1.change(update_preview1, inputs=[image1, top1, left1, bottom1, right1], outputs=preview1)
129
-
130
- image2.change(update_preview2, inputs=[image2, top2, left2, bottom2, right2], outputs=preview2)
131
- top2.change(update_preview2, inputs=[image2, top2, left2, bottom2, right2], outputs=preview2)
132
- left2.change(update_preview2, inputs=[image2, top2, left2, bottom2, right2], outputs=preview2)
133
- bottom2.change(update_preview2, inputs=[image2, top2, left2, bottom2, right2], outputs=preview2)
134
- right2.change(update_preview2, inputs=[image2, top2, left2, bottom2, right2], outputs=preview2)
135
-
136
  generate_button.click(
137
- create_gif_gradio,
138
- inputs=[preview1, preview2, transition_type],
139
- outputs=output_gif
140
  )
141
 
142
  # Launch the interface
 
1
  import gradio as gr
2
+ from PIL import Image
3
  import io
 
 
4
 
5
+ def create_gif(editor_output):
6
+ background = editor_output["background"]
7
+ layers = editor_output["layers"]
8
+ composite = editor_output["composite"]
9
+
10
+ # Use the composite image for GIF creation
11
+ img = composite.convert('RGBA')
12
+
13
  frames = []
14
  duration = 100 # Duration for each frame in milliseconds
15
  total_frames = 18 # Total number of frames
16
 
17
+ size = img.size
18
+ full_width = size[0]
19
+ step = full_width // (total_frames // 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ # Create sliding transition
22
+ for i in range(0, full_width, step):
23
+ frame = Image.new('RGBA', size)
24
+ frame.paste(img.crop((0, 0, i, size[1])), (0, 0))
25
+ frame.paste(img.crop((i, 0, full_width, size[1])), (i, 0))
26
+ frames.append(frame.convert('P', palette=Image.ADAPTIVE))
27
 
28
+ for i in range(full_width, 0, -step):
29
+ frame = Image.new('RGBA', size)
30
+ frame.paste(img.crop((full_width - i, 0, full_width, size[1])), (0, 0))
31
+ frame.paste(img.crop((0, 0, full_width - i, size[1])), (i, 0))
32
+ frames.append(frame.convert('P', palette=Image.ADAPTIVE))
33
 
34
+ # Save as GIF
35
+ output = io.BytesIO()
36
+ frames[0].save(output, format='GIF', save_all=True, append_images=frames[1:], duration=duration, loop=0, optimize=True)
37
+ output.seek(0)
38
 
 
 
 
39
  # Save the GIF to a temporary file
40
  temp_output_path = "output.gif"
41
  with open(temp_output_path, "wb") as f:
42
+ f.write(output.getvalue())
43
 
44
  return temp_output_path
45
 
 
 
 
 
 
 
46
  # Gradio interface
47
  with gr.Blocks() as iface:
48
+ gr.Markdown("# Advanced GIF Generator with Image Editing")
49
 
50
  with gr.Row():
51
+ image_editor = gr.ImageEditor(
52
+ label="Edit Your Image",
53
+ brush=gr.Brush(colors=["#ff0000", "#00ff00", "#0000ff"]),
54
+ eraser=gr.Eraser(default_size=10),
55
+ height=500,
56
+ width=500,
57
+ crop_size="1:1",
58
+ layers=True,
59
+ type="pil"
60
+ )
 
 
 
 
 
 
 
61
 
62
  generate_button = gr.Button("Generate GIF")
63
  output_gif = gr.Image(type="filepath", label="Generated GIF")
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  generate_button.click(
66
+ create_gif,
67
+ inputs=[image_editor],
68
+ outputs=[output_gif]
69
  )
70
 
71
  # Launch the interface