Amit Gazal commited on
Commit
80d8afe
·
1 Parent(s): eb5c95c

smart crop

Browse files
Files changed (1) hide show
  1. app.py +56 -6
app.py CHANGED
@@ -239,24 +239,74 @@ def find_place_to_add_text(image: Image.Image, faces: list[dict]) -> tuple[int,
239
  min_text_width, # width
240
  min_text_height # height
241
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
  def run_flow(input_image, holiday, message):
244
  faces = detect_faces(input_image)
245
-
246
- prompt = image_to_prompt(input_image, holiday)
 
247
  print(prompt)
248
- result_image, only_background_image, mask = remove_background(input_image)
249
  dilated_mask = dilate_mask(mask)
250
- output_image = modify_background(input_image, dilated_mask, prompt)
251
 
252
  # Create a copy of the modified image before drawing
253
  output_image_with_text_rectangle = output_image.copy()
254
- text_x_in_percent, text_y_in_percent, text_width_in_percent, text_height_in_percent = find_place_to_add_text(input_image, faces)
255
  text_x = text_x_in_percent * output_image.width
256
  text_y = text_y_in_percent * output_image.height
257
  text_width = text_width_in_percent * output_image.width
258
  text_height = text_height_in_percent * output_image.height
259
- print(text_x, text_y, text_width, text_height)
260
  draw = ImageDraw.Draw(output_image_with_text_rectangle)
261
  draw.rectangle((text_x, text_y, text_x + text_width, text_y + text_height), outline="red")
262
 
 
239
  min_text_width, # width
240
  min_text_height # height
241
  )
242
+
243
+ def crop_to_ratio_while_preventing_faces(image: Image.Image, faces: list[dict]) -> Image.Image:
244
+ ASPECT_RATIO_PORTRAIT = 5/7
245
+ ASPECT_RATIO_LANDSCAPE = 7/5
246
+ image_width, image_height = image.size
247
+
248
+ # Calculate current aspect ratio
249
+ current_ratio = image_width / image_height
250
+ is_portrait = current_ratio < 1
251
+ target_ratio = ASPECT_RATIO_PORTRAIT if is_portrait else ASPECT_RATIO_LANDSCAPE
252
+
253
+ # Calculate new dimensions
254
+ if current_ratio > target_ratio:
255
+ new_width = int(image_height * target_ratio)
256
+ new_height = image_height
257
+ else:
258
+ new_width = image_width
259
+ new_height = int(image_width / target_ratio)
260
+
261
+ # If no faces, just do center crop
262
+ if not faces:
263
+ x = (image_width - new_width) // 2
264
+ y = (image_height - new_height) // 2
265
+ return image.crop((x, y, x + new_width, y + new_height))
266
+
267
+ # Find the bounding box that contains all faces
268
+ face_x1 = min(int(face['bbox'][0]) for face in faces)
269
+ face_y1 = min(int(face['bbox'][1]) for face in faces)
270
+ face_x2 = max(int(face['bbox'][2]) for face in faces)
271
+ face_y2 = max(int(face['bbox'][3]) for face in faces)
272
+
273
+ # Add padding around faces
274
+ padding = 50
275
+ face_x1 = max(0, face_x1 - padding)
276
+ face_y1 = max(0, face_y1 - padding)
277
+ face_x2 = min(image_width, face_x2 + padding)
278
+ face_y2 = min(image_height, face_y2 + padding)
279
+
280
+ # Calculate crop coordinates that ensure faces are included
281
+ x = max(0, min(face_x1, image_width - new_width))
282
+ y = max(0, min(face_y1, image_height - new_height))
283
+
284
+ # Adjust if faces would be cut off
285
+ if x + new_width < face_x2:
286
+ x = max(0, face_x2 - new_width)
287
+ if y + new_height < face_y2:
288
+ y = max(0, face_y2 - new_height)
289
+
290
+ return image.crop((x, y, x + new_width, y + new_height))
291
 
292
  def run_flow(input_image, holiday, message):
293
  faces = detect_faces(input_image)
294
+ cropped_image = crop_to_ratio_while_preventing_faces(input_image, faces)
295
+
296
+ prompt = image_to_prompt(cropped_image, holiday)
297
  print(prompt)
298
+ result_image, only_background_image, mask = remove_background(cropped_image)
299
  dilated_mask = dilate_mask(mask)
300
+ output_image = modify_background(cropped_image, dilated_mask, prompt)
301
 
302
  # Create a copy of the modified image before drawing
303
  output_image_with_text_rectangle = output_image.copy()
304
+ text_x_in_percent, text_y_in_percent, text_width_in_percent, text_height_in_percent = find_place_to_add_text(cropped_image, faces)
305
  text_x = text_x_in_percent * output_image.width
306
  text_y = text_y_in_percent * output_image.height
307
  text_width = text_width_in_percent * output_image.width
308
  text_height = text_height_in_percent * output_image.height
309
+
310
  draw = ImageDraw.Draw(output_image_with_text_rectangle)
311
  draw.rectangle((text_x, text_y, text_x + text_width, text_y + text_height), outline="red")
312