Non-playing-Character commited on
Commit
e289c5c
·
verified ·
1 Parent(s): d402b86

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -0
app.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image, ImageOps
3
+ import numpy as np
4
+ import cv2
5
+
6
+
7
+ def get_new_size_and_padding(old_w, old_h, target_ratio):
8
+ old_ratio = old_w / old_h
9
+ if old_ratio > target_ratio:
10
+ # Image is wider than target: pad height
11
+ new_w = old_w
12
+ new_h = int(old_w / target_ratio)
13
+ pad_top = (new_h - old_h) // 2
14
+ pad_bottom = new_h - old_h - pad_top
15
+ pad_left = pad_right = 0
16
+ else:
17
+ # Image is taller than target: pad width
18
+ new_h = old_h
19
+ new_w = int(old_h * target_ratio)
20
+ pad_left = (new_w - old_w) // 2
21
+ pad_right = new_w - old_w - pad_left
22
+ pad_top = pad_bottom = 0
23
+ return (new_w, new_h), (pad_left, pad_top, pad_right, pad_bottom)
24
+
25
+
26
+ def image_filler(img, padding):
27
+ # Use OpenCV to blur the border region for a simple "image filler"
28
+ np_img = np.array(img)
29
+ h, w = np_img.shape[:2]
30
+ pad_left, pad_top, pad_right, pad_bottom = padding
31
+
32
+ # Create a blurred version of the image
33
+ blurred = cv2.GaussianBlur(np_img, (51, 51), 0)
34
+
35
+ # Create a new image with the blurred background
36
+ new_h = h + pad_top + pad_bottom
37
+ new_w = w + pad_left + pad_right
38
+ result = np.zeros((new_h, new_w, 3), dtype=np.uint8)
39
+ result[:, :] = blurred[0, 0] # Fill with a color from the image
40
+
41
+ # Place the blurred image in the background
42
+ result[:, :] = blurred[0, 0]
43
+ result[pad_top : pad_top + h, pad_left : pad_left + w] = np_img
44
+
45
+ # Blend the edges for a smooth transition
46
+ # (For simplicity, just use the blurred background)
47
+ return Image.fromarray(result)
48
+
49
+
50
+ def resize_with_border(image, aspect_ratio, border_fill):
51
+ # Parse aspect ratio
52
+ w_ratio, h_ratio = map(int, aspect_ratio.split(":"))
53
+ target_ratio = w_ratio / h_ratio
54
+
55
+ # Ensure image is RGB
56
+ image = image.convert("RGB")
57
+ old_w, old_h = image.size
58
+
59
+ (new_w, new_h), padding = get_new_size_and_padding(old_w, old_h, target_ratio)
60
+
61
+ if border_fill == "White":
62
+ # Use Pillow's expand with white fill
63
+ result = ImageOps.expand(image, border=padding, fill=(255, 255, 255))
64
+ else:
65
+ # Use image filler (blurred border)
66
+ result = image_filler(image, padding)
67
+
68
+ # Resize to exact target size (optional, in case of rounding)
69
+ result = result.resize((new_w, new_h), Image.LANCZOS)
70
+ return result
71
+
72
+
73
+ aspect_ratios = ["1:1", "4:3", "16:9", "3:2", "21:9"]
74
+
75
+ with gr.Blocks() as demo:
76
+ gr.Markdown("# Image Resizer with Border Fill")
77
+ with gr.Row():
78
+ with gr.Column():
79
+ image_input = gr.Image(type="pil", label="Upload Image")
80
+ aspect_input = gr.Dropdown(
81
+ aspect_ratios, value="1:1", label="Target Aspect Ratio"
82
+ )
83
+ fill_input = gr.Radio(
84
+ ["White", "Image Filler"], value="White", label="Border Fill"
85
+ )
86
+ submit_btn = gr.Button("Resize Image")
87
+ with gr.Column():
88
+ image_output = gr.Image(type="pil", label="Resized Image")
89
+ submit_btn.click(
90
+ resize_with_border,
91
+ inputs=[image_input, aspect_input, fill_input],
92
+ outputs=image_output,
93
+ )
94
+
95
+ demo.launch()