Spaces:
Sleeping
Sleeping
Amit Gazal
commited on
Commit
·
80d8afe
1
Parent(s):
eb5c95c
smart crop
Browse files
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 |
-
|
|
|
247 |
print(prompt)
|
248 |
-
result_image, only_background_image, mask = remove_background(
|
249 |
dilated_mask = dilate_mask(mask)
|
250 |
-
output_image = modify_background(
|
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(
|
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 |
-
|
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 |
|