svjack commited on
Commit
5121904
·
verified ·
1 Parent(s): 62159de

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +244 -0
app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image
3
+ import numpy as np
4
+
5
+ def create_empty_image():
6
+ """
7
+ Create an empty transparent image (512x512, RGBA mode).
8
+ :return: Empty PIL.Image object.
9
+ """
10
+ return Image.new("RGBA", (512, 512), (0, 0, 0, 0))
11
+
12
+ def overlay_images(images, alphas, positions):
13
+ """
14
+ Overlay multiple semi-transparent layers and control their positions.
15
+ :param images: List of uploaded images (PIL.Image objects).
16
+ :param alphas: List of transparency values for each layer (floats between 0 and 1).
17
+ :param positions: List of positions for each layer, format: [(x1, y1), (x2, y2), ...].
18
+ :return: Overlayed image with transparent background, overlayed image with black background, and list of individual layer images.
19
+ """
20
+ if not images:
21
+ return None, None, []
22
+
23
+ # Create a transparent canvas (1024x1024)
24
+ transparent_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 0))
25
+ # Create a black canvas (1024x1024)
26
+ black_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 255))
27
+ layer_images = [] # Store individual layer images
28
+
29
+ # Overlay each layer
30
+ for i, img in enumerate(images):
31
+ # Ensure the image is a PIL.Image object
32
+ if not isinstance(img, Image.Image):
33
+ img = create_empty_image()
34
+ # Resize the layer to 512x512
35
+ layer = img.convert("RGBA").resize((512, 512))
36
+ # Set transparency
37
+ layer = Image.fromarray(
38
+ (np.array(layer) * np.array([1, 1, 1, alphas[i]])).astype(np.uint8)
39
+ )
40
+ # Get layer position
41
+ x, y = positions[i]
42
+ # Expand from bottom-left to top-right
43
+ x_offset = x # X coordinate starts from 0 and expands to the right
44
+ y_offset = 1024 - y - layer.height # Y coordinate starts from the bottom and expands upward
45
+ # Paste the layer onto the transparent canvas
46
+ transparent_canvas.paste(layer, (x_offset, y_offset), layer)
47
+ # Paste the layer onto the black canvas
48
+ black_canvas.paste(layer, (x_offset, y_offset), layer)
49
+
50
+ # Generate individual layer image
51
+ layer_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 0))
52
+ layer_canvas.paste(layer, (x_offset, y_offset), layer)
53
+ layer_images.append(layer_canvas)
54
+
55
+ # If there are fewer than 4 layers, fill with empty images
56
+ while len(layer_images) < 4:
57
+ layer_images.append(create_empty_image())
58
+
59
+ return transparent_canvas, black_canvas, layer_images
60
+
61
+ def crop_image(image, crop_x_min, crop_x_max, crop_y_min, crop_y_max):
62
+ """
63
+ Crop an image.
64
+ :param image: Input image (PIL.Image object).
65
+ :param crop_x_min: X-axis crop start point.
66
+ :param crop_x_max: X-axis crop end point.
67
+ :param crop_y_min: Y-axis crop start point.
68
+ :param crop_y_max: Y-axis crop end point.
69
+ :return: Cropped image (PIL.Image object).
70
+ """
71
+ if image is None:
72
+ return None
73
+ # Ensure the crop range is within the image dimensions
74
+ x_min = max(0, min(crop_x_min, image.width))
75
+ x_max = max(0, min(crop_x_max, image.width))
76
+ y_min = max(0, min(crop_y_min, image.height))
77
+ y_max = max(0, min(crop_y_max, image.height))
78
+ # Crop the image
79
+ return image.crop((x_min, y_min, x_max, y_max))
80
+
81
+ def update_output(image1, image2, image3, image4, alpha1, alpha2, alpha3, alpha4, x1, y1, x2, y2, x3, y3, x4, y4, crop_x_min, crop_x_max, crop_y_min, crop_y_max):
82
+ """
83
+ Update the output images.
84
+ :param image1, image2, image3, image4: Uploaded images.
85
+ :param alpha1, alpha2, alpha3, alpha4: Transparency values for each layer.
86
+ :param x1, y1, x2, y2, x3, y3, x4, y4: Positions for each layer.
87
+ :param crop_x_min: X-axis crop start point.
88
+ :param crop_x_max: X-axis crop end point.
89
+ :param crop_y_min: Y-axis crop start point.
90
+ :param crop_y_max: Y-axis crop end point.
91
+ :return: Cropped transparent background image, black background image, and individual layer images.
92
+ """
93
+ # Print logs to check the type and content of each input
94
+ print("image1:", type(image1), image1)
95
+ print("image2:", type(image2), image2)
96
+ print("image3:", type(image3), image3)
97
+ print("image4:", type(image4), image4)
98
+ print("alpha1:", type(alpha1), alpha1)
99
+ print("alpha2:", type(alpha2), alpha2)
100
+ print("alpha3:", type(alpha3), alpha3)
101
+ print("alpha4:", type(alpha4), alpha4)
102
+ print("x1:", type(x1), x1)
103
+ print("y1:", type(y1), y1)
104
+ print("x2:", type(x2), x2)
105
+ print("y2:", type(y2), y2)
106
+ print("x3:", type(x3), x3)
107
+ print("y3:", type(y3), y3)
108
+ print("x4:", type(x4), x4)
109
+ print("y4:", type(y4), y4)
110
+ print("crop_x_min:", type(crop_x_min), crop_x_min)
111
+ print("crop_x_max:", type(crop_x_max), crop_x_max)
112
+ print("crop_y_min:", type(crop_y_min), crop_y_min)
113
+ print("crop_y_max:", type(crop_y_max), crop_y_max)
114
+
115
+ # If an image is None, use an empty image
116
+ images = [
117
+ image1 if image1 is not None else create_empty_image(),
118
+ image2 if image2 is not None else create_empty_image(),
119
+ image3 if image3 is not None else create_empty_image(),
120
+ image4 if image4 is not None else create_empty_image()
121
+ ]
122
+ alphas = [alpha1, alpha2, alpha3, alpha4] # Transparency list
123
+ positions = [(x1, y1), (x2, y2), (x3, y3), (x4, y4)] # Position list
124
+
125
+ # Call the overlay function
126
+ transparent_image, black_image, layer_images = overlay_images(images, alphas, positions)
127
+
128
+ # Crop the output images
129
+ transparent_image = crop_image(transparent_image, crop_x_min, crop_x_max, crop_y_min, crop_y_max)
130
+ black_image = crop_image(black_image, crop_x_min, crop_x_max, crop_y_min, crop_y_max)
131
+ layer_images = [crop_image(img, crop_x_min, crop_x_max, crop_y_min, crop_y_max) for img in layer_images]
132
+
133
+ # Return 6 values (cropped transparent background image + black background image + 4 individual layer images)
134
+ return [transparent_image, black_image] + layer_images
135
+
136
+ # Example data
137
+ example_images = [
138
+ Image.open("furina_yellow.webp") if "furina_yellow.webp" else create_empty_image(),
139
+ Image.open("nilou_blue.webp") if "nilou_blue.webp" else create_empty_image(),
140
+ create_empty_image(), # Layer 3 is an empty image
141
+ create_empty_image() # Layer 4 is an empty image
142
+ ]
143
+ example_alphas = [1.0, 1.0, 1.0, 1.0] # Example transparency values
144
+ example_positions = [(101, 0), (264, 0), (0, 0), (0, 0)] # Example positions
145
+ example_crop_x = (160, 850) # Example X-axis crop range
146
+ example_crop_y = (360, 1020) # Example Y-axis crop range
147
+
148
+ # Gradio interface
149
+ with gr.Blocks() as demo:
150
+ gr.Markdown("## 🎨 Layer Overlay Application")
151
+ gr.Markdown("Upload multiple semi-transparent layers (PNG format), set transparency and position, and generate the overlayed image.")
152
+
153
+ with gr.Row():
154
+ # Left column: Inputs
155
+ with gr.Column():
156
+ gr.Markdown("### Upload Layers")
157
+ image1 = gr.Image(label="Layer 1", type="pil", image_mode="RGBA")
158
+ image2 = gr.Image(label="Layer 2", type="pil", image_mode="RGBA")
159
+ image3 = gr.Image(label="Layer 3", type="pil", image_mode="RGBA")
160
+ image4 = gr.Image(label="Layer 4", type="pil", image_mode="RGBA")
161
+
162
+ gr.Markdown("### Set Transparency")
163
+ alpha1 = gr.Slider(0, 1, value=1, label="Layer 1 Transparency")
164
+ alpha2 = gr.Slider(0, 1, value=1, label="Layer 2 Transparency")
165
+ alpha3 = gr.Slider(0, 1, value=1, label="Layer 3 Transparency")
166
+ alpha4 = gr.Slider(0, 1, value=1, label="Layer 4 Transparency")
167
+
168
+ gr.Markdown("### Set Positions")
169
+ with gr.Row():
170
+ x1 = gr.Slider(0, 512, value=0, label="Layer 1 X Position")
171
+ y1 = gr.Slider(0, 512, value=0, label="Layer 1 Y Position")
172
+ with gr.Row():
173
+ x2 = gr.Slider(0, 512, value=0, label="Layer 2 X Position")
174
+ y2 = gr.Slider(0, 512, value=0, label="Layer 2 Y Position")
175
+ with gr.Row():
176
+ x3 = gr.Slider(0, 512, value=0, label="Layer 3 X Position")
177
+ y3 = gr.Slider(0, 512, value=0, label="Layer 3 Y Position")
178
+ with gr.Row():
179
+ x4 = gr.Slider(0, 512, value=0, label="Layer 4 X Position")
180
+ y4 = gr.Slider(0, 512, value=0, label="Layer 4 Y Position")
181
+
182
+ gr.Markdown("### Set Crop Range")
183
+ with gr.Row():
184
+ crop_x_min = gr.Slider(0, 1024, value=0, label="X-axis Crop Start")
185
+ crop_x_max = gr.Slider(0, 1024, value=1024, label="X-axis Crop End")
186
+ with gr.Row():
187
+ crop_y_min = gr.Slider(0, 1024, value=0, label="Y-axis Crop Start")
188
+ crop_y_max = gr.Slider(0, 1024, value=1024, label="Y-axis Crop End")
189
+
190
+ run_button = gr.Button("Generate Overlayed Image")
191
+
192
+ # Right column: Outputs
193
+ with gr.Column():
194
+ gr.Markdown("### Overlay Results")
195
+ transparent_output = gr.Image(label="Overlayed Image (Transparent Background)", type="pil")
196
+ black_output = gr.Image(label="Overlayed Image (Black Background)", type="pil")
197
+ gr.Markdown("### Individual Layer Images")
198
+ layer1_image = gr.Image(label="Layer 1 Image", type="pil")
199
+ layer2_image = gr.Image(label="Layer 2 Image", type="pil")
200
+ layer3_image = gr.Image(label="Layer 3 Image", type="pil")
201
+ layer4_image = gr.Image(label="Layer 4 Image", type="pil")
202
+
203
+ # Bind events
204
+ run_button.click(
205
+ update_output,
206
+ inputs=[
207
+ image1, image2, image3, image4, # Images
208
+ alpha1, alpha2, alpha3, alpha4, # Transparency
209
+ x1, y1, x2, y2, x3, y3, x4, y4, # Positions
210
+ crop_x_min, crop_x_max, # X-axis crop range
211
+ crop_y_min, crop_y_max # Y-axis crop range
212
+ ],
213
+ outputs=[transparent_output, black_output, layer1_image, layer2_image, layer3_image, layer4_image]
214
+ )
215
+
216
+ # Add examples
217
+ gr.Examples(
218
+ examples=[
219
+ [
220
+ example_images[0], example_images[1], example_images[2], example_images[3], # Images
221
+ example_alphas[0], example_alphas[1], example_alphas[2], example_alphas[3], # Transparency
222
+ example_positions[0][0], example_positions[0][1], # Layer 1 position
223
+ example_positions[1][0], example_positions[1][1], # Layer 2 position
224
+ example_positions[2][0], example_positions[2][1], # Layer 3 position
225
+ example_positions[3][0], example_positions[3][1], # Layer 4 position
226
+ example_crop_x[0], example_crop_x[1], # X-axis crop range
227
+ example_crop_y[0], example_crop_y[1] # Y-axis crop range
228
+ ]
229
+ ],
230
+ inputs=[
231
+ image1, image2, image3, image4, # Images
232
+ alpha1, alpha2, alpha3, alpha4, # Transparency
233
+ x1, y1, x2, y2, x3, y3, x4, y4, # Positions
234
+ crop_x_min, crop_x_max, # X-axis crop range
235
+ crop_y_min, crop_y_max # Y-axis crop range
236
+ ],
237
+ outputs=[transparent_output, black_output, layer1_image, layer2_image, layer3_image, layer4_image],
238
+ fn=update_output,
239
+ cache_examples=True
240
+ )
241
+
242
+ # Launch the application
243
+ if __name__ == "__main__":
244
+ demo.launch(share=True)