Spaces:
Sleeping
Sleeping
File size: 11,285 Bytes
5121904 4308008 5121904 |
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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
import gradio as gr
from PIL import Image
import numpy as np
def create_empty_image():
"""
Create an empty transparent image (512x512, RGBA mode).
:return: Empty PIL.Image object.
"""
return Image.new("RGBA", (512, 512), (0, 0, 0, 0))
def overlay_images(images, alphas, positions):
"""
Overlay multiple semi-transparent layers and control their positions.
:param images: List of uploaded images (PIL.Image objects).
:param alphas: List of transparency values for each layer (floats between 0 and 1).
:param positions: List of positions for each layer, format: [(x1, y1), (x2, y2), ...].
:return: Overlayed image with transparent background, overlayed image with black background, and list of individual layer images.
"""
if not images:
return None, None, []
# Create a transparent canvas (1024x1024)
transparent_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 0))
# Create a black canvas (1024x1024)
black_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 255))
layer_images = [] # Store individual layer images
# Overlay each layer
for i, img in enumerate(images):
# Ensure the image is a PIL.Image object
if not isinstance(img, Image.Image):
img = create_empty_image()
# Resize the layer to 512x512
layer = img.convert("RGBA").resize((512, 512))
# Set transparency
layer = Image.fromarray(
(np.array(layer) * np.array([1, 1, 1, alphas[i]])).astype(np.uint8)
)
# Get layer position
x, y = positions[i]
# Expand from bottom-left to top-right
x_offset = x # X coordinate starts from 0 and expands to the right
y_offset = 1024 - y - layer.height # Y coordinate starts from the bottom and expands upward
# Paste the layer onto the transparent canvas
transparent_canvas.paste(layer, (x_offset, y_offset), layer)
# Paste the layer onto the black canvas
black_canvas.paste(layer, (x_offset, y_offset), layer)
# Generate individual layer image
layer_canvas = Image.new("RGBA", (1024, 1024), (0, 0, 0, 0))
layer_canvas.paste(layer, (x_offset, y_offset), layer)
layer_images.append(layer_canvas)
# If there are fewer than 4 layers, fill with empty images
while len(layer_images) < 4:
layer_images.append(create_empty_image())
return transparent_canvas, black_canvas, layer_images
def crop_image(image, crop_x_min, crop_x_max, crop_y_min, crop_y_max):
"""
Crop an image.
:param image: Input image (PIL.Image object).
:param crop_x_min: X-axis crop start point.
:param crop_x_max: X-axis crop end point.
:param crop_y_min: Y-axis crop start point.
:param crop_y_max: Y-axis crop end point.
:return: Cropped image (PIL.Image object).
"""
if image is None:
return None
# Ensure the crop range is within the image dimensions
x_min = max(0, min(crop_x_min, image.width))
x_max = max(0, min(crop_x_max, image.width))
y_min = max(0, min(crop_y_min, image.height))
y_max = max(0, min(crop_y_max, image.height))
# Crop the image
return image.crop((x_min, y_min, x_max, y_max))
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):
"""
Update the output images.
:param image1, image2, image3, image4: Uploaded images.
:param alpha1, alpha2, alpha3, alpha4: Transparency values for each layer.
:param x1, y1, x2, y2, x3, y3, x4, y4: Positions for each layer.
:param crop_x_min: X-axis crop start point.
:param crop_x_max: X-axis crop end point.
:param crop_y_min: Y-axis crop start point.
:param crop_y_max: Y-axis crop end point.
:return: Cropped transparent background image, black background image, and individual layer images.
"""
# Print logs to check the type and content of each input
print("image1:", type(image1), image1)
print("image2:", type(image2), image2)
print("image3:", type(image3), image3)
print("image4:", type(image4), image4)
print("alpha1:", type(alpha1), alpha1)
print("alpha2:", type(alpha2), alpha2)
print("alpha3:", type(alpha3), alpha3)
print("alpha4:", type(alpha4), alpha4)
print("x1:", type(x1), x1)
print("y1:", type(y1), y1)
print("x2:", type(x2), x2)
print("y2:", type(y2), y2)
print("x3:", type(x3), x3)
print("y3:", type(y3), y3)
print("x4:", type(x4), x4)
print("y4:", type(y4), y4)
print("crop_x_min:", type(crop_x_min), crop_x_min)
print("crop_x_max:", type(crop_x_max), crop_x_max)
print("crop_y_min:", type(crop_y_min), crop_y_min)
print("crop_y_max:", type(crop_y_max), crop_y_max)
# If an image is None, use an empty image
images = [
image1 if image1 is not None else create_empty_image(),
image2 if image2 is not None else create_empty_image(),
image3 if image3 is not None else create_empty_image(),
image4 if image4 is not None else create_empty_image()
]
alphas = [alpha1, alpha2, alpha3, alpha4] # Transparency list
positions = [(x1, y1), (x2, y2), (x3, y3), (x4, y4)] # Position list
# Call the overlay function
transparent_image, black_image, layer_images = overlay_images(images, alphas, positions)
# Crop the output images
transparent_image = crop_image(transparent_image, crop_x_min, crop_x_max, crop_y_min, crop_y_max)
black_image = crop_image(black_image, crop_x_min, crop_x_max, crop_y_min, crop_y_max)
layer_images = [crop_image(img, crop_x_min, crop_x_max, crop_y_min, crop_y_max) for img in layer_images]
# Return 6 values (cropped transparent background image + black background image + 4 individual layer images)
return [transparent_image, black_image] + layer_images
# Example data
example_images = [
Image.open("芙宁娜_yellow.webp") if "芙宁娜_yellow.webp" else create_empty_image(),
Image.open("妮露_blue.webp") if "妮露_blue.webp" else create_empty_image(),
create_empty_image(), # Layer 3 is an empty image
create_empty_image() # Layer 4 is an empty image
]
example_alphas = [1.0, 1.0, 1.0, 1.0] # Example transparency values
example_positions = [(101, 0), (264, 0), (0, 0), (0, 0)] # Example positions
example_crop_x = (160, 850) # Example X-axis crop range
example_crop_y = (360, 1020) # Example Y-axis crop range
# Gradio interface
with gr.Blocks() as demo:
gr.Markdown("## 🎨 Layer Overlay Application")
gr.Markdown("Upload multiple semi-transparent layers (PNG format), set transparency and position, and generate the overlayed image.")
with gr.Row():
# Left column: Inputs
with gr.Column():
gr.Markdown("### Upload Layers")
image1 = gr.Image(label="Layer 1", type="pil", image_mode="RGBA")
image2 = gr.Image(label="Layer 2", type="pil", image_mode="RGBA")
image3 = gr.Image(label="Layer 3", type="pil", image_mode="RGBA")
image4 = gr.Image(label="Layer 4", type="pil", image_mode="RGBA")
gr.Markdown("### Set Transparency")
alpha1 = gr.Slider(0, 1, value=1, label="Layer 1 Transparency")
alpha2 = gr.Slider(0, 1, value=1, label="Layer 2 Transparency")
alpha3 = gr.Slider(0, 1, value=1, label="Layer 3 Transparency")
alpha4 = gr.Slider(0, 1, value=1, label="Layer 4 Transparency")
gr.Markdown("### Set Positions")
with gr.Row():
x1 = gr.Slider(0, 512, value=0, label="Layer 1 X Position")
y1 = gr.Slider(0, 512, value=0, label="Layer 1 Y Position")
with gr.Row():
x2 = gr.Slider(0, 512, value=0, label="Layer 2 X Position")
y2 = gr.Slider(0, 512, value=0, label="Layer 2 Y Position")
with gr.Row():
x3 = gr.Slider(0, 512, value=0, label="Layer 3 X Position")
y3 = gr.Slider(0, 512, value=0, label="Layer 3 Y Position")
with gr.Row():
x4 = gr.Slider(0, 512, value=0, label="Layer 4 X Position")
y4 = gr.Slider(0, 512, value=0, label="Layer 4 Y Position")
gr.Markdown("### Set Crop Range")
with gr.Row():
crop_x_min = gr.Slider(0, 1024, value=0, label="X-axis Crop Start")
crop_x_max = gr.Slider(0, 1024, value=1024, label="X-axis Crop End")
with gr.Row():
crop_y_min = gr.Slider(0, 1024, value=0, label="Y-axis Crop Start")
crop_y_max = gr.Slider(0, 1024, value=1024, label="Y-axis Crop End")
run_button = gr.Button("Generate Overlayed Image")
# Right column: Outputs
with gr.Column():
gr.Markdown("### Overlay Results")
transparent_output = gr.Image(label="Overlayed Image (Transparent Background)", type="pil")
black_output = gr.Image(label="Overlayed Image (Black Background)", type="pil")
gr.Markdown("### Individual Layer Images")
layer1_image = gr.Image(label="Layer 1 Image", type="pil")
layer2_image = gr.Image(label="Layer 2 Image", type="pil")
layer3_image = gr.Image(label="Layer 3 Image", type="pil")
layer4_image = gr.Image(label="Layer 4 Image", type="pil")
# Bind events
run_button.click(
update_output,
inputs=[
image1, image2, image3, image4, # Images
alpha1, alpha2, alpha3, alpha4, # Transparency
x1, y1, x2, y2, x3, y3, x4, y4, # Positions
crop_x_min, crop_x_max, # X-axis crop range
crop_y_min, crop_y_max # Y-axis crop range
],
outputs=[transparent_output, black_output, layer1_image, layer2_image, layer3_image, layer4_image]
)
# Add examples
gr.Examples(
examples=[
[
example_images[0], example_images[1], example_images[2], example_images[3], # Images
example_alphas[0], example_alphas[1], example_alphas[2], example_alphas[3], # Transparency
example_positions[0][0], example_positions[0][1], # Layer 1 position
example_positions[1][0], example_positions[1][1], # Layer 2 position
example_positions[2][0], example_positions[2][1], # Layer 3 position
example_positions[3][0], example_positions[3][1], # Layer 4 position
example_crop_x[0], example_crop_x[1], # X-axis crop range
example_crop_y[0], example_crop_y[1] # Y-axis crop range
]
],
inputs=[
image1, image2, image3, image4, # Images
alpha1, alpha2, alpha3, alpha4, # Transparency
x1, y1, x2, y2, x3, y3, x4, y4, # Positions
crop_x_min, crop_x_max, # X-axis crop range
crop_y_min, crop_y_max # Y-axis crop range
],
outputs=[transparent_output, black_output, layer1_image, layer2_image, layer3_image, layer4_image],
fn=update_output,
cache_examples=True
)
# Launch the application
if __name__ == "__main__":
demo.launch(share=True) |