StickerMaker / app.py
cr8's picture
Update app.py
01a1d5c verified
import gradio as gr
from PIL import Image, ImageFilter
import rembg
import io
import base64
def process_image(image, outline_size, outline_color):
if image is None:
return None
try:
# Convert image to bytes for rembg
img_byte_arr = io.BytesIO()
image.save(img_byte_arr, format="PNG", dpi=(300, 300)) # Set DPI here
img_byte_arr.seek(0)
# Remove background
processed_bytes = rembg.remove(img_byte_arr.getvalue())
processed_img = Image.open(io.BytesIO(processed_bytes)).convert("RGBA")
# Create outline mask
alpha = processed_img.split()[-1]
alpha = Image.merge('L', [alpha])
blurred = alpha.filter(ImageFilter.GaussianBlur(radius=outline_size))
new_alpha = blurred.point(lambda x: 0 if x == 0 else 255) # Binary mask
# Define outline color based on selection
if outline_color == "white":
outline_rgb = (255, 255, 255, 255) # White
elif outline_color == "black":
outline_rgb = (0, 0, 0, 255) # Black
else:
outline_rgb = (255, 255, 255, 255) #Default white
# Apply outline to the transparent image
outlined_img = Image.new("RGBA", processed_img.size, (0, 0, 0, 0)) # Fully transparent
pixels = outlined_img.load()
alpha_pixels = new_alpha.load()
for x in range(outlined_img.width):
for y in range(outlined_img.height):
if alpha_pixels[x, y] > 0:
pixels[x, y] = outline_rgb
# Overlay original image
outlined_img = Image.alpha_composite(outlined_img, processed_img)
# Save the result as bytes for Gradio
output_buffer = io.BytesIO()
outlined_img.save(output_buffer, format="PNG", dpi=(300, 300)) # Set DPI here
output_buffer.seek(0)
img_data = base64.b64encode(output_buffer.read()).decode("utf-8")
data_url = f"data:image/png;base64,{img_data}"
return data_url # Return data_url for display
except Exception as e:
print(f"Error processing image: {e}") # Log the error
return None
# Gradio Interface
with gr.Blocks(title="Sticker Maker") as interface:
gr.Markdown("# Sticker Maker")
gr.Markdown("Upload an image to remove the background and add an outline.")
with gr.Row():
with gr.Column():
image_upload = gr.Image(label="Upload Image", type="pil")
outline_size = gr.Slider(
label="Outline Thickness", minimum=0, maximum=20, value=5, step=1
)
outline_color = gr.Radio(
choices=["white", "black"],
value="white",
label="Outline Color",
)
create_btn = gr.Button("Create Sticker", variant="primary")
with gr.Column():
image_output_html = gr.HTML(
"""
<div style="position: relative;">
<img id="sticker-preview" src="" style="max-width: 100%; max-height: 400px;">
<a id="download-link" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px; display:none;" download="sticker.png">Download</a>
</div>
"""
)
def update_image(image, outline_size, outline_color):
try:
data_url = process_image(image, outline_size, outline_color)
if data_url:
return f"""
<div style="position: relative;">
<img id="sticker-preview" src="{data_url}" style="max-width: 100%; max-height: 400px;">
<a id="download-link" href="{data_url}" download="sticker.png" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px;">Download</a>
</div>
"""
else:
return """
<div style="position: relative;">
<img id="sticker-preview" src="" style="max-width: 100%; max-height: 400px;">
<a id="download-link" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px; display:none;" download="sticker.png">Download</a>
</div>
"""
except Exception as e:
print(f"Error in update_image: {e}") # Log the error
return f"""
<div style="position: relative;">
Error: {e}
</div>
"""
create_btn.click(
fn=update_image,
inputs=[image_upload, outline_size, outline_color],
outputs=image_output_html,
)
if __name__ == "__main__":
interface.launch(debug=True)