b2bomber's picture
Update app.py
60487a4 verified
raw
history blame
4.26 kB
# app.py
# A user-friendly version with a custom download button, inspired by the watermark remover app.
import gradio as gr
from rembg import remove
import traceback
from PIL import Image
import tempfile # Used to create temporary files for downloading
# --- Core Function ---
# This function processes the image. It remains the same.
def process_image(input_image):
"""
Removes the background from an image.
Handles errors gracefully.
"""
if input_image is None:
raise gr.Error("Please upload an image or select one of the examples.")
try:
# Use the default rembg model for stability
return remove(input_image)
except Exception as e:
print(traceback.format_exc())
raise gr.Error(f"Failed to process image: {e}")
# --- Download Function ---
# This function correctly prepares the image for download.
def prepare_for_download(image):
"""
Saves the processed PIL image to a temporary file and returns the path.
This is the correct way to trigger a download in Gradio.
"""
if image is None:
# Prevent an error if the download button is clicked before an image is processed.
return None
try:
# Create a temporary file with a '.png' extension.
# 'delete=False' is important so the file is not deleted before Gradio serves it.
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
image.save(tmp.name)
# Return the path to the temporary file
return tmp.name
except Exception as e:
print(f"Error creating download file: {e}")
return None
# --- Gradio App with Modern UI ---
# We inject CSS to hide the default utility buttons on the output image.
with gr.Blocks(
theme=gr.themes.Soft(primary_hue="violet"),
css="#output_image .meta-buttons { display: none !important; }"
) as demo:
gr.Markdown(
"""
Upload an image, use your webcam, or try one of the examples below to instantly remove the background.
"""
)
# Main two-column layout
with gr.Row(variant="panel"):
# --- Input Column ---
with gr.Column(scale=1, min_width=300):
image_input = gr.Image(
type="pil",
label="Upload or Drag an Image",
sources=["upload", "webcam"],
height=400
)
with gr.Row():
clear_btn = gr.ClearButton(
value="Clear",
components=[image_input],
variant="secondary"
)
submit_btn = gr.Button("Remove Background", variant="primary")
# --- Output Column ---
with gr.Column(scale=1, min_width=300):
# We give the output image an ID so we can target it with CSS
image_output = gr.Image(
elem_id="output_image",
type="pil",
label="Result",
height=400,
interactive=False # This disables the upload overlay on the result
)
# ✅ NEW: Use a gr.File component for the download, which is more reliable.
# This will appear as a download link/button when populated.
download_output = gr.File(label="Download Result", visible=False)
# --- Event Listeners ---
def on_submit(input_img):
# This function runs when the user clicks submit.
# It processes the image and then prepares it for download.
processed_img = process_image(input_img)
download_path = prepare_for_download(processed_img)
# It returns the processed image to the preview box,
# and the downloadable file to the (now visible) download component.
return processed_img, gr.update(value=download_path, visible=True)
submit_btn.click(
fn=on_submit,
inputs=image_input,
outputs=[image_output, download_output]
)
# When the user clicks "Clear", also hide the download button.
clear_btn.click(lambda: gr.update(visible=False), outputs=[download_output])
# --- Launch the App ---
if __name__ == "__main__":
demo.launch()