|
|
import gradio as gr
|
|
|
from PIL import Image, ImageOps
|
|
|
import numpy as np
|
|
|
import cv2
|
|
|
|
|
|
|
|
|
def get_new_size_and_padding(old_w, old_h, target_ratio):
|
|
|
old_ratio = old_w / old_h
|
|
|
if old_ratio > target_ratio:
|
|
|
|
|
|
new_w = old_w
|
|
|
new_h = int(old_w / target_ratio)
|
|
|
pad_top = (new_h - old_h) // 2
|
|
|
pad_bottom = new_h - old_h - pad_top
|
|
|
pad_left = pad_right = 0
|
|
|
else:
|
|
|
|
|
|
new_h = old_h
|
|
|
new_w = int(old_h * target_ratio)
|
|
|
pad_left = (new_w - old_w) // 2
|
|
|
pad_right = new_w - old_w - pad_left
|
|
|
pad_top = pad_bottom = 0
|
|
|
return (new_w, new_h), (pad_left, pad_top, pad_right, pad_bottom)
|
|
|
|
|
|
|
|
|
def image_filler(img, padding):
|
|
|
|
|
|
np_img = np.array(img)
|
|
|
h, w = np_img.shape[:2]
|
|
|
pad_left, pad_top, pad_right, pad_bottom = padding
|
|
|
|
|
|
|
|
|
blurred = cv2.GaussianBlur(np_img, (51, 51), 0)
|
|
|
|
|
|
|
|
|
new_h = h + pad_top + pad_bottom
|
|
|
new_w = w + pad_left + pad_right
|
|
|
result = np.zeros((new_h, new_w, 3), dtype=np.uint8)
|
|
|
result[:, :] = blurred[0, 0]
|
|
|
|
|
|
|
|
|
result[:, :] = blurred[0, 0]
|
|
|
result[pad_top : pad_top + h, pad_left : pad_left + w] = np_img
|
|
|
|
|
|
|
|
|
|
|
|
return Image.fromarray(result)
|
|
|
|
|
|
|
|
|
def resize_with_border(image, aspect_ratio, border_fill):
|
|
|
|
|
|
w_ratio, h_ratio = map(int, aspect_ratio.split(":"))
|
|
|
target_ratio = w_ratio / h_ratio
|
|
|
|
|
|
|
|
|
image = image.convert("RGB")
|
|
|
old_w, old_h = image.size
|
|
|
|
|
|
(new_w, new_h), padding = get_new_size_and_padding(old_w, old_h, target_ratio)
|
|
|
|
|
|
if border_fill == "White":
|
|
|
|
|
|
result = ImageOps.expand(image, border=padding, fill=(255, 255, 255))
|
|
|
else:
|
|
|
|
|
|
result = image_filler(image, padding)
|
|
|
|
|
|
|
|
|
result = result.resize((new_w, new_h), Image.LANCZOS)
|
|
|
return result
|
|
|
|
|
|
|
|
|
aspect_ratios = ["1:1", "4:3", "16:9", "3:2", "21:9"]
|
|
|
|
|
|
with gr.Blocks() as demo:
|
|
|
gr.Markdown("# Image Resizer with Border Fill")
|
|
|
with gr.Row():
|
|
|
with gr.Column():
|
|
|
image_input = gr.Image(type="pil", label="Upload Image")
|
|
|
aspect_input = gr.Dropdown(
|
|
|
aspect_ratios, value="1:1", label="Target Aspect Ratio"
|
|
|
)
|
|
|
fill_input = gr.Radio(
|
|
|
["White", "Image Filler"], value="White", label="Border Fill"
|
|
|
)
|
|
|
submit_btn = gr.Button("Resize Image")
|
|
|
with gr.Column():
|
|
|
image_output = gr.Image(type="pil", label="Resized Image")
|
|
|
submit_btn.click(
|
|
|
resize_with_border,
|
|
|
inputs=[image_input, aspect_input, fill_input],
|
|
|
outputs=image_output,
|
|
|
)
|
|
|
|
|
|
demo.launch()
|
|
|
|