File size: 4,258 Bytes
97bc3cc
60487a4
97bc3cc
 
 
7e456f1
82bd866
60487a4
97bc3cc
81c32e2
60487a4
94cf2c3
81c32e2
 
 
 
97bc3cc
81c32e2
 
97bc3cc
60487a4
94cf2c3
97bc3cc
7e456f1
a01173c
97bc3cc
f542d97
60487a4
 
a01173c
82bd866
60487a4
a01173c
82bd866
 
 
 
60487a4
 
82bd866
 
 
 
 
 
 
f542d97
81c32e2
60487a4
f542d97
 
60487a4
f542d97
81c32e2
 
 
 
 
 
 
60487a4
81c32e2
 
 
 
 
 
 
 
 
 
 
60487a4
81c32e2
 
 
 
 
 
 
97bc3cc
81c32e2
 
60487a4
81c32e2
60487a4
81c32e2
 
 
60487a4
81c32e2
f542d97
60487a4
 
 
f542d97
81c32e2
60487a4
 
 
 
 
 
 
 
 
81c32e2
60487a4
81c32e2
60487a4
f542d97
 
60487a4
 
81c32e2
 
97bc3cc
f542d97
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
# 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()