Harzis commited on
Commit
c91789f
·
verified ·
1 Parent(s): 42b94c5

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +251 -0
  2. requirements.txt +1 -1
app.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ from rembg import remove
4
+ from PIL import Image
5
+ import io
6
+ import zipfile
7
+ from typing import List, Tuple, Union, IO, Optional
8
+ import spaces
9
+
10
+ @spaces.GPU
11
+ def remove_background_single(image_file: Union[str, IO[bytes]]) -> Optional[Image.Image]:
12
+ """Removes the background from a single image.
13
+
14
+ This function takes an image file (either as a path or a file-like object),
15
+ processes it to remove the background, and returns the result as a
16
+ Pillow (PIL) Image object with a transparent background.
17
+
18
+ Args:
19
+ image_file: The input image. Can be a path to a
20
+ file on disk or a file-like object (e.g., from a file upload).
21
+
22
+ Returns:
23
+ A Pillow Image object with the background removed, or None if
24
+ the input was None.
25
+ """
26
+ if image_file is None:
27
+ return None
28
+
29
+ # Read the image data
30
+ if hasattr(image_file, 'read'):
31
+ input_data = image_file.read()
32
+ else:
33
+ with open(image_file, 'rb') as f:
34
+ input_data = f.read()
35
+
36
+ # Remove background
37
+ output_data = remove(input_data)
38
+
39
+ # Convert to PIL Image
40
+ output_image = Image.open(io.BytesIO(output_data))
41
+ return output_image
42
+
43
+ @spaces.GPU
44
+ def remove_background_multiple(image_files: List[Union[str, IO[bytes]]]) -> Tuple[Optional[str], List[Image.Image]]:
45
+ """Removes backgrounds from multiple images and provides a zip archive.
46
+
47
+ This function processes a list of image files. For each image, it removes
48
+ the background, then bundles all the processed images (in PNG format)
49
+ into a single zip file for download. It also returns a small number of
50
+ processed images as previews for display in the UI.
51
+
52
+ Args:
53
+ image_files: A list of input images. Each element can be a
54
+ path to a file or a file-like object.
55
+
56
+ Returns:
57
+ A tuple containing:
58
+ - A string with the file path to the generated zip archive. This
59
+ is `None` if the input list was empty.
60
+ - A list of up to 5 processed Pillow Image objects to be used
61
+ as a preview.
62
+ """
63
+ if not image_files:
64
+ return None, []
65
+
66
+ processed_images = []
67
+ preview_images = []
68
+
69
+ # Create a zip file in memory
70
+ zip_buffer = io.BytesIO()
71
+
72
+ with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
73
+ for i, image_file in enumerate(image_files):
74
+ try:
75
+ # Get original filename or create one
76
+ if hasattr(image_file, 'name') and image_file.name:
77
+ original_name = os.path.basename(image_file.name)
78
+ name_without_ext = os.path.splitext(original_name)[0]
79
+ else:
80
+ name_without_ext = f"image_{i+1}"
81
+
82
+ # Remove background
83
+ processed_image = remove_background_single(image_file)
84
+
85
+ if processed_image:
86
+ # Save to zip file
87
+ img_buffer = io.BytesIO()
88
+ processed_image.save(img_buffer, format='PNG')
89
+ img_buffer.seek(0)
90
+
91
+ zip_file.writestr(f"{name_without_ext}_no_bg.png", img_buffer.getvalue())
92
+
93
+ # Add to preview (limit to first 5 images for display)
94
+ if len(preview_images) < 5:
95
+ preview_images.append(processed_image)
96
+
97
+ except Exception as e:
98
+ print(f"Error processing image {i+1}: {str(e)}")
99
+ continue
100
+
101
+ zip_buffer.seek(0)
102
+
103
+ # Save zip file temporarily
104
+ zip_path = "processed_images.zip"
105
+ with open(zip_path, 'wb') as f:
106
+ f.write(zip_buffer.getvalue())
107
+
108
+ return zip_path, preview_images
109
+
110
+ def process_images(single_image, multiple_images, processing_mode):
111
+ """Main processing function based on selected mode"""
112
+ if processing_mode == "Single Image":
113
+ if single_image is None:
114
+ return None, None, None, "Please upload an image first."
115
+
116
+ try:
117
+ result = remove_background_single(single_image)
118
+ return result, None, None, "Background removed successfully!"
119
+ except Exception as e:
120
+ return None, None, None, f"Error processing image: {str(e)}"
121
+
122
+ else: # Multiple Images
123
+ if not multiple_images:
124
+ return None, None, None, "Please upload at least one image."
125
+
126
+ try:
127
+ zip_file, preview_images = remove_background_multiple(multiple_images)
128
+ if zip_file and preview_images:
129
+ return None, preview_images, zip_file, f"Processed {len(multiple_images)} images successfully! Download the zip file to get all results."
130
+ else:
131
+ return None, None, None, "No images were processed successfully."
132
+ except Exception as e:
133
+ return None, None, None, f"Error processing images: {str(e)}"
134
+
135
+ # Create Gradio interface
136
+ with gr.Blocks(title="Background Removal Tool", theme=gr.themes.Default()) as app:
137
+ gr.Markdown(
138
+ """
139
+ # 🖼️ Background Removal Tool
140
+
141
+ Upload your images and get them back with transparent backgrounds!
142
+
143
+ **Choose your mode:**
144
+ - **Single Image**: Upload one image and preview the result
145
+ - **Multiple Images**: Upload multiple images and download them as a zip file
146
+ """
147
+ )
148
+
149
+ with gr.Row():
150
+ processing_mode = gr.Radio(
151
+ choices=["Single Image", "Multiple Images"],
152
+ value="Single Image",
153
+ label="Processing Mode"
154
+ )
155
+
156
+ with gr.Row():
157
+ with gr.Column():
158
+ # Single image input (visible by default)
159
+ single_image_input = gr.File(
160
+ label="Upload Single Image",
161
+ file_types=["image"],
162
+ visible=True
163
+ )
164
+
165
+ # Multiple images input (hidden by default)
166
+ multiple_images_input = gr.File(
167
+ label="Upload Multiple Images",
168
+ file_count="multiple",
169
+ file_types=["image"],
170
+ visible=False
171
+ )
172
+
173
+ process_btn = gr.Button("Remove Background", variant="primary", size="lg")
174
+
175
+ with gr.Column():
176
+ # Output for single image
177
+ single_output = gr.Image(
178
+ label="Result",
179
+ visible=True
180
+ )
181
+
182
+ # Output for multiple images
183
+ multiple_output_gallery = gr.Gallery(
184
+ label="Preview (first 5 images)",
185
+ visible=False,
186
+ columns=3,
187
+ rows=2,
188
+ height="auto"
189
+ )
190
+
191
+ download_file = gr.File(
192
+ label="Download All Processed Images",
193
+ visible=False
194
+ )
195
+
196
+ status_message = gr.Textbox(label="Status", interactive=False)
197
+
198
+ # Function to toggle visibility based on mode
199
+ def toggle_inputs(mode):
200
+ if mode == "Single Image":
201
+ return (
202
+ gr.update(visible=True), # single_image_input
203
+ gr.update(visible=False), # multiple_images_input
204
+ gr.update(visible=True), # single_output
205
+ gr.update(visible=False), # multiple_output_gallery
206
+ gr.update(visible=False) # download_file
207
+ )
208
+ else:
209
+ return (
210
+ gr.update(visible=False), # single_image_input
211
+ gr.update(visible=True), # multiple_images_input
212
+ gr.update(visible=False), # single_output
213
+ gr.update(visible=True), # multiple_output_gallery
214
+ gr.update(visible=True) # download_file
215
+ )
216
+
217
+ # Toggle inputs when mode changes
218
+ processing_mode.change(
219
+ fn=toggle_inputs,
220
+ inputs=[processing_mode],
221
+ outputs=[single_image_input, multiple_images_input, single_output, multiple_output_gallery, download_file]
222
+ )
223
+
224
+ # Process images when button is clicked
225
+ process_btn.click(
226
+ fn=process_images,
227
+ inputs=[single_image_input, multiple_images_input, processing_mode],
228
+ outputs=[single_output, multiple_output_gallery, download_file, status_message]
229
+ )
230
+
231
+ # Remove the separate gallery update function since we're handling it directly now
232
+
233
+ gr.Markdown(
234
+ """
235
+ ### 📝 Instructions:
236
+ 1. Choose your processing mode (Single or Multiple images)
237
+ 2. Upload your image(s) - supports PNG, JPG, JPEG formats
238
+ 3. Click "Remove Background" to process
239
+ 4. For single images: preview the result directly
240
+ 5. For multiple images: download the zip file containing all processed images
241
+
242
+ ### ⚡ Features:
243
+ - Automatic background removal using AI
244
+ - Support for batch processing
245
+ - Transparent PNG output
246
+ - Easy download of results
247
+ """
248
+ )
249
+
250
+ if __name__ == "__main__":
251
+ app.launch(mcp_server=True)
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- gradio>=4.0.0
2
  rembg>=2.0.0
3
  pillow>=9.0.0
4
  numpy>=1.21.0
 
1
+ gradio[mcp]>=4.0.0
2
  rembg>=2.0.0
3
  pillow>=9.0.0
4
  numpy>=1.21.0