Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,13 +1,14 @@
|
|
| 1 |
# app.py
|
| 2 |
-
# A
|
| 3 |
|
| 4 |
import gradio as gr
|
| 5 |
from rembg import remove
|
| 6 |
import traceback
|
| 7 |
from PIL import Image
|
| 8 |
-
import tempfile #
|
| 9 |
|
| 10 |
# --- Core Function ---
|
|
|
|
| 11 |
def process_image(input_image):
|
| 12 |
"""
|
| 13 |
Removes the background from an image.
|
|
@@ -17,24 +18,25 @@ def process_image(input_image):
|
|
| 17 |
raise gr.Error("Please upload an image or select one of the examples.")
|
| 18 |
|
| 19 |
try:
|
|
|
|
| 20 |
return remove(input_image)
|
| 21 |
except Exception as e:
|
| 22 |
print(traceback.format_exc())
|
| 23 |
raise gr.Error(f"Failed to process image: {e}")
|
| 24 |
|
| 25 |
# --- Download Function ---
|
| 26 |
-
#
|
| 27 |
-
|
| 28 |
-
def download_output_image(image):
|
| 29 |
"""
|
| 30 |
Saves the processed PIL image to a temporary file and returns the path.
|
|
|
|
| 31 |
"""
|
| 32 |
if image is None:
|
| 33 |
# Prevent an error if the download button is clicked before an image is processed.
|
| 34 |
return None
|
| 35 |
try:
|
| 36 |
-
# Create a temporary file with a '.png' extension.
|
| 37 |
-
# so the file is not deleted before Gradio
|
| 38 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
| 39 |
image.save(tmp.name)
|
| 40 |
# Return the path to the temporary file
|
|
@@ -44,9 +46,10 @@ def download_output_image(image):
|
|
| 44 |
return None
|
| 45 |
|
| 46 |
# --- Gradio App with Modern UI ---
|
|
|
|
| 47 |
with gr.Blocks(
|
| 48 |
theme=gr.themes.Soft(primary_hue="violet"),
|
| 49 |
-
css=".meta-buttons { display: none !important; }"
|
| 50 |
) as demo:
|
| 51 |
|
| 52 |
gr.Markdown(
|
|
@@ -55,6 +58,7 @@ with gr.Blocks(
|
|
| 55 |
"""
|
| 56 |
)
|
| 57 |
|
|
|
|
| 58 |
with gr.Row(variant="panel"):
|
| 59 |
|
| 60 |
# --- Input Column ---
|
|
@@ -66,7 +70,7 @@ with gr.Blocks(
|
|
| 66 |
height=400
|
| 67 |
)
|
| 68 |
|
| 69 |
-
|
| 70 |
with gr.Row():
|
| 71 |
clear_btn = gr.ClearButton(
|
| 72 |
value="Clear",
|
|
@@ -77,40 +81,37 @@ with gr.Blocks(
|
|
| 77 |
|
| 78 |
# --- Output Column ---
|
| 79 |
with gr.Column(scale=1, min_width=300):
|
|
|
|
| 80 |
image_output = gr.Image(
|
|
|
|
| 81 |
type="pil",
|
| 82 |
label="Result",
|
| 83 |
height=400,
|
| 84 |
-
|
| 85 |
-
show_download_button=False,
|
| 86 |
-
interactive=False
|
| 87 |
-
)
|
| 88 |
-
|
| 89 |
-
download_button = gr.Button(
|
| 90 |
-
"Download Image",
|
| 91 |
-
icon="https://cdn.iconscout.com/icon/premium/png-256-thumb/download-button-2132338-1794935.png",
|
| 92 |
-
variant="primary",
|
| 93 |
)
|
| 94 |
|
| 95 |
-
#
|
| 96 |
-
|
|
|
|
| 97 |
|
| 98 |
# --- Event Listeners ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
submit_btn.click(
|
| 100 |
-
fn=
|
| 101 |
inputs=image_input,
|
| 102 |
-
outputs=image_output,
|
| 103 |
-
api_name="predict"
|
| 104 |
-
)
|
| 105 |
-
|
| 106 |
-
# The download button click event remains the same, but the function it calls is now fixed.
|
| 107 |
-
download_button.click(
|
| 108 |
-
fn=download_output_image,
|
| 109 |
-
inputs=[image_output],
|
| 110 |
-
outputs=[download_file_output]
|
| 111 |
)
|
| 112 |
|
| 113 |
-
|
|
|
|
| 114 |
|
| 115 |
# --- Launch the App ---
|
| 116 |
if __name__ == "__main__":
|
|
|
|
| 1 |
# app.py
|
| 2 |
+
# A user-friendly version with a custom download button, inspired by the watermark remover app.
|
| 3 |
|
| 4 |
import gradio as gr
|
| 5 |
from rembg import remove
|
| 6 |
import traceback
|
| 7 |
from PIL import Image
|
| 8 |
+
import tempfile # Used to create temporary files for downloading
|
| 9 |
|
| 10 |
# --- Core Function ---
|
| 11 |
+
# This function processes the image. It remains the same.
|
| 12 |
def process_image(input_image):
|
| 13 |
"""
|
| 14 |
Removes the background from an image.
|
|
|
|
| 18 |
raise gr.Error("Please upload an image or select one of the examples.")
|
| 19 |
|
| 20 |
try:
|
| 21 |
+
# Use the default rembg model for stability
|
| 22 |
return remove(input_image)
|
| 23 |
except Exception as e:
|
| 24 |
print(traceback.format_exc())
|
| 25 |
raise gr.Error(f"Failed to process image: {e}")
|
| 26 |
|
| 27 |
# --- Download Function ---
|
| 28 |
+
# This function correctly prepares the image for download.
|
| 29 |
+
def prepare_for_download(image):
|
|
|
|
| 30 |
"""
|
| 31 |
Saves the processed PIL image to a temporary file and returns the path.
|
| 32 |
+
This is the correct way to trigger a download in Gradio.
|
| 33 |
"""
|
| 34 |
if image is None:
|
| 35 |
# Prevent an error if the download button is clicked before an image is processed.
|
| 36 |
return None
|
| 37 |
try:
|
| 38 |
+
# Create a temporary file with a '.png' extension.
|
| 39 |
+
# 'delete=False' is important so the file is not deleted before Gradio serves it.
|
| 40 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
| 41 |
image.save(tmp.name)
|
| 42 |
# Return the path to the temporary file
|
|
|
|
| 46 |
return None
|
| 47 |
|
| 48 |
# --- Gradio App with Modern UI ---
|
| 49 |
+
# We inject CSS to hide the default utility buttons on the output image.
|
| 50 |
with gr.Blocks(
|
| 51 |
theme=gr.themes.Soft(primary_hue="violet"),
|
| 52 |
+
css="#output_image .meta-buttons { display: none !important; }"
|
| 53 |
) as demo:
|
| 54 |
|
| 55 |
gr.Markdown(
|
|
|
|
| 58 |
"""
|
| 59 |
)
|
| 60 |
|
| 61 |
+
# Main two-column layout
|
| 62 |
with gr.Row(variant="panel"):
|
| 63 |
|
| 64 |
# --- Input Column ---
|
|
|
|
| 70 |
height=400
|
| 71 |
)
|
| 72 |
|
| 73 |
+
|
| 74 |
with gr.Row():
|
| 75 |
clear_btn = gr.ClearButton(
|
| 76 |
value="Clear",
|
|
|
|
| 81 |
|
| 82 |
# --- Output Column ---
|
| 83 |
with gr.Column(scale=1, min_width=300):
|
| 84 |
+
# We give the output image an ID so we can target it with CSS
|
| 85 |
image_output = gr.Image(
|
| 86 |
+
elem_id="output_image",
|
| 87 |
type="pil",
|
| 88 |
label="Result",
|
| 89 |
height=400,
|
| 90 |
+
interactive=False # This disables the upload overlay on the result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
)
|
| 92 |
|
| 93 |
+
# ✅ NEW: Use a gr.File component for the download, which is more reliable.
|
| 94 |
+
# This will appear as a download link/button when populated.
|
| 95 |
+
download_output = gr.File(label="Download Result", visible=False)
|
| 96 |
|
| 97 |
# --- Event Listeners ---
|
| 98 |
+
def on_submit(input_img):
|
| 99 |
+
# This function runs when the user clicks submit.
|
| 100 |
+
# It processes the image and then prepares it for download.
|
| 101 |
+
processed_img = process_image(input_img)
|
| 102 |
+
download_path = prepare_for_download(processed_img)
|
| 103 |
+
# It returns the processed image to the preview box,
|
| 104 |
+
# and the downloadable file to the (now visible) download component.
|
| 105 |
+
return processed_img, gr.update(value=download_path, visible=True)
|
| 106 |
+
|
| 107 |
submit_btn.click(
|
| 108 |
+
fn=on_submit,
|
| 109 |
inputs=image_input,
|
| 110 |
+
outputs=[image_output, download_output]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
)
|
| 112 |
|
| 113 |
+
# When the user clicks "Clear", also hide the download button.
|
| 114 |
+
clear_btn.click(lambda: gr.update(visible=False), outputs=[download_output])
|
| 115 |
|
| 116 |
# --- Launch the App ---
|
| 117 |
if __name__ == "__main__":
|