Zeph27 commited on
Commit
d243471
·
1 Parent(s): 2c91766

change tread logic

Browse files
Files changed (1) hide show
  1. app.py +27 -51
app.py CHANGED
@@ -6,30 +6,24 @@ from PIL import Image
6
  import io
7
  from rembg import remove
8
  import gradio as gr
9
- from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
10
  from transformers import pipeline
11
 
12
  def colors_within_tolerance(color1, color2, tolerance):
13
  return all(abs(c1 - c2) <= tolerance for c1, c2 in zip(color1, color2))
14
 
15
  def check_border_colors(image_path, tolerance):
16
- # Open the image
17
  image = Image.open(image_path)
18
  pixels = image.load()
19
 
20
  width, height = image.size
21
 
22
- # Get the color of the first pixel on the left and right borders
23
  left_border_color = pixels[0, 0]
24
  right_border_color = pixels[width - 1, 0]
25
 
26
- # Check the left border
27
  for y in range(height):
28
  if not colors_within_tolerance(pixels[0, y], left_border_color, tolerance):
29
  return False
30
-
31
- # Check the right border
32
- for y in range(height):
33
  if not colors_within_tolerance(pixels[width - 1, y], right_border_color, tolerance):
34
  return False
35
 
@@ -41,10 +35,8 @@ def resize_and_crop_image(image_path, target_size=(1080, 1080), crop_mode='cente
41
  width, height = img.size
42
  print(f"Original image size: {width}x{height}")
43
 
44
- # Calculate the scaling factor
45
  scaling_factor = max(target_size[0] / width, target_size[1] / height)
46
 
47
- # Resize the image with high-quality resampling
48
  new_size = (int(width * scaling_factor), int(height * scaling_factor))
49
  resized_img = img.resize(new_size, Image.LANCZOS)
50
  print(f"Resized image size: {new_size}")
@@ -68,7 +60,6 @@ def resize_and_crop_image(image_path, target_size=(1080, 1080), crop_mode='cente
68
  right = left + target_size[0]
69
  bottom = top + target_size[1]
70
 
71
- # Crop the image
72
  cropped_img = resized_img.crop((left, top, right, bottom))
73
  print(f"Cropped image size: {cropped_img.size}")
74
 
@@ -85,7 +76,7 @@ def remove_background_rembg(input_path):
85
  def remove_background_bria(input_path):
86
  print(f"Removing background using bria for image: {input_path}")
87
  pipe = pipeline("image-segmentation", model="briaai/RMBG-1.4", trust_remote_code=True)
88
- pillow_image = pipe(input_path) # applies mask on input and returns a pillow image
89
  return pillow_image
90
 
91
  def process_single_image(image_path, output_folder, crop_mode, bg_method, output_format, bg_choice, custom_color, watermark_path=None):
@@ -93,25 +84,20 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
93
  try:
94
  print(f"Processing image: {filename}")
95
  if bg_method == 'rembg':
96
- # Remove background using rembg
97
  image_with_no_bg = remove_background_rembg(image_path)
98
  elif bg_method == 'bria':
99
- # Remove background using bria
100
  image_with_no_bg = remove_background_bria(image_path)
101
 
102
  temp_image_path = os.path.join(output_folder, f"temp_{filename}")
103
  image_with_no_bg.save(temp_image_path, format='PNG')
104
 
105
- # Check border colors and categorize
106
  if check_border_colors(temp_image_path, tolerance=50):
107
  print(f"Border colors are the same for image: {filename}")
108
- # Create a new 1080x1080 canvas
109
  if bg_choice == 'transparent':
110
  new_image = Image.new("RGBA", (1080, 1080), (255, 255, 255, 0))
111
  else:
112
  new_image = Image.new("RGBA", (1080, 1080), custom_color)
113
 
114
- # Scale image to fit inside the canvas without stretching
115
  width, height = image_with_no_bg.size
116
  scaling_factor = min(1080 / width, 1080 / height)
117
  new_size = (int(width * scaling_factor), int(height * scaling_factor))
@@ -122,7 +108,6 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
122
  print(f"Border colors are different for image: {filename}")
123
  new_image = resize_and_crop_image(temp_image_path, crop_mode=crop_mode)
124
 
125
- # Change background color if needed
126
  if bg_choice == 'white':
127
  new_image = new_image.convert("RGBA")
128
  white_bg = Image.new("RGBA", new_image.size, "WHITE")
@@ -132,10 +117,8 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
132
  custom_bg = Image.new("RGBA", new_image.size, custom_color)
133
  new_image = Image.alpha_composite(custom_bg, new_image)
134
 
135
- # Save both versions of the image (with and without watermark)
136
  images_paths = []
137
 
138
- # Save without watermark
139
  output_ext = 'jpg' if output_format == 'JPG' else 'png'
140
  output_path_without_watermark = os.path.join(output_folder, f"without_watermark_{os.path.splitext(filename)[0]}.{output_ext}")
141
  if output_format == 'JPG':
@@ -144,7 +127,6 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
144
  new_image.save(output_path_without_watermark, format='PNG')
145
  images_paths.append(output_path_without_watermark)
146
 
147
- # Apply watermark if provided and save the version with watermark
148
  if watermark_path:
149
  watermark = Image.open(watermark_path).convert("RGBA")
150
  new_image_with_watermark = new_image.copy()
@@ -156,7 +138,6 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
156
  new_image_with_watermark.save(output_path_with_watermark, format='PNG')
157
  images_paths.append(output_path_with_watermark)
158
 
159
- # Remove the temporary file
160
  os.remove(temp_image_path)
161
 
162
  print(f"Processed image paths: {images_paths}")
@@ -169,7 +150,6 @@ def process_single_image(image_path, output_folder, crop_mode, bg_method, output
169
  def process_images(zip_file, crop_mode='center', bg_method='rembg', watermark_path=None, output_format='PNG', bg_choice='transparent', custom_color="#ffffff", num_workers=4, progress=gr.Progress()):
170
  start_time = time.time()
171
 
172
- # Create a temporary directory
173
  input_folder = "temp_input"
174
  output_folder = "temp_output"
175
  if os.path.exists(input_folder):
@@ -179,7 +159,6 @@ def process_images(zip_file, crop_mode='center', bg_method='rembg', watermark_pa
179
  os.makedirs(input_folder)
180
  os.makedirs(output_folder)
181
 
182
- # Extract the zip file
183
  try:
184
  with zipfile.ZipFile(zip_file, 'r') as zip_ref:
185
  zip_ref.extractall(input_folder)
@@ -188,25 +167,23 @@ def process_images(zip_file, crop_mode='center', bg_method='rembg', watermark_pa
188
  return [], None, 0
189
 
190
  processed_images = []
 
191
  image_files = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
192
  total_images = len(image_files)
193
  print(f"Total images to process: {total_images}")
194
 
195
- # Process images using ThreadPoolExecutor for I/O-bound tasks and ProcessPoolExecutor for CPU-bound tasks
196
- with ThreadPoolExecutor(max_workers=num_workers) as thread_executor:
197
- with ProcessPoolExecutor(max_workers=num_workers) as process_executor:
198
- future_to_image = {thread_executor.submit(process_single_image, image_path, output_folder, crop_mode, bg_method, output_format, bg_choice, custom_color, watermark_path): image_path for image_path in image_files}
199
- for idx, future in enumerate(future_to_image):
200
- try:
201
- result = future.result()
202
- if result:
203
- processed_images.extend(result)
204
- except Exception as e:
205
- print(f"Error processing image {future_to_image[future]}: {e}")
206
- # Update progress
207
- progress((idx + 1) / total_images, f"{idx + 1}/{total_images} images processed")
208
-
209
- # Create a zip file of the processed images
210
  output_zip_path = "processed_images.zip"
211
  with zipfile.ZipFile(output_zip_path, 'w') as zipf:
212
  for file in processed_images:
@@ -219,11 +196,10 @@ def process_images(zip_file, crop_mode='center', bg_method='rembg', watermark_pa
219
  processing_time = end_time - start_time
220
  print(f"Processing time: {processing_time} seconds")
221
 
222
- # Return the images, the zip file path, and processing time
223
- return processed_images, output_zip_path, processing_time
224
 
225
  def gradio_interface(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers):
226
- progress = gr.Progress() # Initialize progress
227
  watermark_path = watermark.name if watermark else None
228
  return process_images(zip_file.name, crop_mode, bg_method, watermark_path, output_format, bg_choice, custom_color, num_workers, progress)
229
 
@@ -237,7 +213,6 @@ def show_color_picker(bg_choice):
237
  return gr.update(visible=True)
238
  return gr.update(visible=False)
239
 
240
- # Create the Gradio interface
241
  with gr.Blocks() as iface:
242
  gr.Markdown("# Image Background Removal and Resizing with Optional Watermark")
243
  gr.Markdown("Upload a ZIP or RAR file containing images, choose the crop mode, optionally upload a watermark image, and select the output format.")
@@ -248,7 +223,6 @@ with gr.Blocks() as iface:
248
 
249
  with gr.Row():
250
  crop_mode = gr.Radio(choices=["center", "top", "bottom", "left", "right"], label="Crop Mode", value="center")
251
-
252
  output_format = gr.Radio(choices=["PNG", "JPG"], label="Output Format", value="PNG")
253
  num_workers = gr.Slider(minimum=1, maximum=16, step=1, label="Number of Workers", value=2)
254
 
@@ -257,19 +231,21 @@ with gr.Blocks() as iface:
257
  bg_choice = gr.Radio(choices=["transparent", "white", "custom"], label="Background Choice", value="transparent", visible=True)
258
  custom_color = gr.ColorPicker(label="Custom Background Color", value="#ffffff", visible=False)
259
 
 
 
 
 
 
 
 
260
  bg_choice.change(show_color_picker, inputs=bg_choice, outputs=custom_color)
261
  output_format.change(show_bg_choice, inputs=output_format, outputs=bg_choice)
262
 
263
- gallery = gr.Gallery(label="Processed Images")
264
- output_zip = gr.File(label="Download Processed Images as ZIP")
265
- processing_time = gr.Textbox(label="Processing Time (seconds)")
266
-
267
  def process(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers):
268
- processed_images, zip_path, time_taken = gradio_interface(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers)
269
- return processed_images, zip_path, f"{time_taken:.2f} seconds"
270
 
271
  process_button = gr.Button("Process Images")
272
- process_button.click(process, inputs=[zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers], outputs=[gallery, output_zip, processing_time])
273
 
274
- # Launch the interface
275
  iface.launch()
 
6
  import io
7
  from rembg import remove
8
  import gradio as gr
9
+ from concurrent.futures import ThreadPoolExecutor
10
  from transformers import pipeline
11
 
12
  def colors_within_tolerance(color1, color2, tolerance):
13
  return all(abs(c1 - c2) <= tolerance for c1, c2 in zip(color1, color2))
14
 
15
  def check_border_colors(image_path, tolerance):
 
16
  image = Image.open(image_path)
17
  pixels = image.load()
18
 
19
  width, height = image.size
20
 
 
21
  left_border_color = pixels[0, 0]
22
  right_border_color = pixels[width - 1, 0]
23
 
 
24
  for y in range(height):
25
  if not colors_within_tolerance(pixels[0, y], left_border_color, tolerance):
26
  return False
 
 
 
27
  if not colors_within_tolerance(pixels[width - 1, y], right_border_color, tolerance):
28
  return False
29
 
 
35
  width, height = img.size
36
  print(f"Original image size: {width}x{height}")
37
 
 
38
  scaling_factor = max(target_size[0] / width, target_size[1] / height)
39
 
 
40
  new_size = (int(width * scaling_factor), int(height * scaling_factor))
41
  resized_img = img.resize(new_size, Image.LANCZOS)
42
  print(f"Resized image size: {new_size}")
 
60
  right = left + target_size[0]
61
  bottom = top + target_size[1]
62
 
 
63
  cropped_img = resized_img.crop((left, top, right, bottom))
64
  print(f"Cropped image size: {cropped_img.size}")
65
 
 
76
  def remove_background_bria(input_path):
77
  print(f"Removing background using bria for image: {input_path}")
78
  pipe = pipeline("image-segmentation", model="briaai/RMBG-1.4", trust_remote_code=True)
79
+ pillow_image = pipe(input_path)
80
  return pillow_image
81
 
82
  def process_single_image(image_path, output_folder, crop_mode, bg_method, output_format, bg_choice, custom_color, watermark_path=None):
 
84
  try:
85
  print(f"Processing image: {filename}")
86
  if bg_method == 'rembg':
 
87
  image_with_no_bg = remove_background_rembg(image_path)
88
  elif bg_method == 'bria':
 
89
  image_with_no_bg = remove_background_bria(image_path)
90
 
91
  temp_image_path = os.path.join(output_folder, f"temp_{filename}")
92
  image_with_no_bg.save(temp_image_path, format='PNG')
93
 
 
94
  if check_border_colors(temp_image_path, tolerance=50):
95
  print(f"Border colors are the same for image: {filename}")
 
96
  if bg_choice == 'transparent':
97
  new_image = Image.new("RGBA", (1080, 1080), (255, 255, 255, 0))
98
  else:
99
  new_image = Image.new("RGBA", (1080, 1080), custom_color)
100
 
 
101
  width, height = image_with_no_bg.size
102
  scaling_factor = min(1080 / width, 1080 / height)
103
  new_size = (int(width * scaling_factor), int(height * scaling_factor))
 
108
  print(f"Border colors are different for image: {filename}")
109
  new_image = resize_and_crop_image(temp_image_path, crop_mode=crop_mode)
110
 
 
111
  if bg_choice == 'white':
112
  new_image = new_image.convert("RGBA")
113
  white_bg = Image.new("RGBA", new_image.size, "WHITE")
 
117
  custom_bg = Image.new("RGBA", new_image.size, custom_color)
118
  new_image = Image.alpha_composite(custom_bg, new_image)
119
 
 
120
  images_paths = []
121
 
 
122
  output_ext = 'jpg' if output_format == 'JPG' else 'png'
123
  output_path_without_watermark = os.path.join(output_folder, f"without_watermark_{os.path.splitext(filename)[0]}.{output_ext}")
124
  if output_format == 'JPG':
 
127
  new_image.save(output_path_without_watermark, format='PNG')
128
  images_paths.append(output_path_without_watermark)
129
 
 
130
  if watermark_path:
131
  watermark = Image.open(watermark_path).convert("RGBA")
132
  new_image_with_watermark = new_image.copy()
 
138
  new_image_with_watermark.save(output_path_with_watermark, format='PNG')
139
  images_paths.append(output_path_with_watermark)
140
 
 
141
  os.remove(temp_image_path)
142
 
143
  print(f"Processed image paths: {images_paths}")
 
150
  def process_images(zip_file, crop_mode='center', bg_method='rembg', watermark_path=None, output_format='PNG', bg_choice='transparent', custom_color="#ffffff", num_workers=4, progress=gr.Progress()):
151
  start_time = time.time()
152
 
 
153
  input_folder = "temp_input"
154
  output_folder = "temp_output"
155
  if os.path.exists(input_folder):
 
159
  os.makedirs(input_folder)
160
  os.makedirs(output_folder)
161
 
 
162
  try:
163
  with zipfile.ZipFile(zip_file, 'r') as zip_ref:
164
  zip_ref.extractall(input_folder)
 
167
  return [], None, 0
168
 
169
  processed_images = []
170
+ original_images = []
171
  image_files = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
172
  total_images = len(image_files)
173
  print(f"Total images to process: {total_images}")
174
 
175
+ with ThreadPoolExecutor(max_workers=num_workers) as executor:
176
+ future_to_image = {executor.submit(process_single_image, image_path, output_folder, crop_mode, bg_method, output_format, bg_choice, custom_color, watermark_path): image_path for image_path in image_files}
177
+ for idx, future in enumerate(future_to_image):
178
+ try:
179
+ result = future.result()
180
+ if result:
181
+ processed_images.extend(result)
182
+ original_images.append(future_to_image[future])
183
+ except Exception as e:
184
+ print(f"Error processing image {future_to_image[future]}: {e}")
185
+ progress((idx + 1) / total_images, f"{idx + 1}/{total_images} images processed")
186
+
 
 
 
187
  output_zip_path = "processed_images.zip"
188
  with zipfile.ZipFile(output_zip_path, 'w') as zipf:
189
  for file in processed_images:
 
196
  processing_time = end_time - start_time
197
  print(f"Processing time: {processing_time} seconds")
198
 
199
+ return original_images, processed_images, output_zip_path, processing_time
 
200
 
201
  def gradio_interface(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers):
202
+ progress = gr.Progress()
203
  watermark_path = watermark.name if watermark else None
204
  return process_images(zip_file.name, crop_mode, bg_method, watermark_path, output_format, bg_choice, custom_color, num_workers, progress)
205
 
 
213
  return gr.update(visible=True)
214
  return gr.update(visible=False)
215
 
 
216
  with gr.Blocks() as iface:
217
  gr.Markdown("# Image Background Removal and Resizing with Optional Watermark")
218
  gr.Markdown("Upload a ZIP or RAR file containing images, choose the crop mode, optionally upload a watermark image, and select the output format.")
 
223
 
224
  with gr.Row():
225
  crop_mode = gr.Radio(choices=["center", "top", "bottom", "left", "right"], label="Crop Mode", value="center")
 
226
  output_format = gr.Radio(choices=["PNG", "JPG"], label="Output Format", value="PNG")
227
  num_workers = gr.Slider(minimum=1, maximum=16, step=1, label="Number of Workers", value=2)
228
 
 
231
  bg_choice = gr.Radio(choices=["transparent", "white", "custom"], label="Background Choice", value="transparent", visible=True)
232
  custom_color = gr.ColorPicker(label="Custom Background Color", value="#ffffff", visible=False)
233
 
234
+ with gr.Row():
235
+ gallery_original = gr.Gallery(label="Original Images")
236
+ gallery_processed = gr.Gallery(label="Processed Images")
237
+ with gr.Row():
238
+ output_zip = gr.File(label="Download Processed Images as ZIP")
239
+ processing_time = gr.Textbox(label="Processing Time (seconds)")
240
+
241
  bg_choice.change(show_color_picker, inputs=bg_choice, outputs=custom_color)
242
  output_format.change(show_bg_choice, inputs=output_format, outputs=bg_choice)
243
 
 
 
 
 
244
  def process(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers):
245
+ original_images, processed_images, zip_path, time_taken = gradio_interface(zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers)
246
+ return original_images, processed_images, zip_path, f"{time_taken:.2f} seconds"
247
 
248
  process_button = gr.Button("Process Images")
249
+ process_button.click(process, inputs=[zip_file, crop_mode, bg_method, watermark, output_format, bg_choice, custom_color, num_workers], outputs=[gallery_original, gallery_processed, output_zip, processing_time])
250
 
 
251
  iface.launch()