Spaces:
Sleeping
Sleeping
import gradio as gr | |
import numpy as np | |
from PIL import Image | |
def apply_overlay(final_x, final_y, final_width, final_height, design_img, target_img): | |
# Convert to PIL images | |
design_image = Image.fromarray(design_img).convert("RGBA") | |
target_image = Image.fromarray(target_img).convert("RGBA") | |
# Resize the design image based on the final dimensions | |
design_image = design_image.resize((final_width, final_height), Image.Resampling.LANCZOS) | |
# Create a transparent overlay | |
overlay = Image.new('RGBA', target_image.size, (255, 255, 255, 0)) | |
overlay.paste(design_image, (final_x, final_y), design_image) | |
# Merge overlay with target image | |
combined_image = Image.alpha_composite(target_image, overlay) | |
return np.array(combined_image) | |
with gr.Blocks() as editor: | |
gr.Markdown("## Drag, Drop, and Resize Your Design") | |
with gr.Row(): | |
design_img = gr.Image(label="Design Image", type="numpy") | |
target_img = gr.Image(label="Target Image", type="numpy") | |
overlay_result = gr.Image(label="Overlay Result") | |
# Hidden elements to store the final positioning and size after user interaction | |
final_x = gr.Number(value=0, visible=False) | |
final_y = gr.Number(value=0, visible=False) | |
final_width = gr.Number(value=100, visible=False) | |
final_height = gr.Number(value=100, visible=False) | |
apply_overlay_btn = gr.Button("Apply Overlay") | |
# JavaScript code for dragging, resizing, and cropping | |
custom_js = """ | |
<script> | |
let designImg = document.querySelector('img[data-target="design_img"]'); | |
let targetImg = document.querySelector('img[data-target="target_img"]'); | |
let resultImg = document.querySelector('img[data-target="overlay_result"]'); | |
let finalX = document.querySelector('input[name="final_x"]'); | |
let finalY = document.querySelector('input[name="final_y"]'); | |
let finalWidth = document.querySelector('input[name="final_width"]'); | |
let finalHeight = document.querySelector('input[name="final_height"]'); | |
let active = false; | |
let currentX, currentY, initialX, initialY; | |
let offsetX = 0, offsetY = 0; | |
designImg.style.position = "absolute"; | |
designImg.style.cursor = "move"; | |
designImg.style.zIndex = "10"; | |
function dragStart(e) { | |
active = true; | |
initialX = e.clientX - offsetX; | |
initialY = e.clientY - offsetY; | |
} | |
function dragEnd() { | |
active = false; | |
offsetX = currentX; | |
offsetY = currentY; | |
finalX.value = offsetX; | |
finalY.value = offsetY; | |
finalWidth.value = designImg.width; | |
finalHeight.value = designImg.height; | |
} | |
function drag(e) { | |
if (active) { | |
e.preventDefault(); | |
currentX = e.clientX - initialX; | |
currentY = e.clientY - initialY; | |
designImg.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`; | |
} | |
} | |
designImg.addEventListener("mousedown", dragStart); | |
window.addEventListener("mouseup", dragEnd); | |
window.addEventListener("mousemove", drag); | |
designImg.addEventListener("wheel", (e) => { | |
e.preventDefault(); | |
let newWidth = designImg.width + (e.deltaY < 0 ? 10 : -10); | |
let newHeight = designImg.height + (e.deltaY < 0 ? 10 : -10); | |
if (newWidth > 50 && newHeight > 50) { | |
designImg.style.width = `${newWidth}px`; | |
designImg.style.height = `${newHeight}px`; | |
} | |
}); | |
</script> | |
""" | |
html_code = gr.HTML(custom_js) | |
# Apply overlay on clicking the button | |
apply_overlay_btn.click(apply_overlay, [final_x, final_y, final_width, final_height, design_img, target_img], overlay_result) | |
editor.launch() | |