Spaces:
Sleeping
Sleeping
| 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: | |
| # Image is wider than target: pad height | |
| 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: | |
| # Image is taller than target: pad width | |
| 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): | |
| # Use OpenCV to blur the border region for a simple "image filler" | |
| np_img = np.array(img) | |
| h, w = np_img.shape[:2] | |
| pad_left, pad_top, pad_right, pad_bottom = padding | |
| # Create a blurred version of the image | |
| blurred = cv2.GaussianBlur(np_img, (51, 51), 0) | |
| # Create a new image with the blurred background | |
| 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] # Fill with a color from the image | |
| # Place the blurred image in the background | |
| result[:, :] = blurred[0, 0] | |
| result[pad_top : pad_top + h, pad_left : pad_left + w] = np_img | |
| # Blend the edges for a smooth transition | |
| # (For simplicity, just use the blurred background) | |
| return Image.fromarray(result) | |
| def resize_with_border(image, aspect_ratio, border_fill): | |
| # Parse aspect ratio | |
| w_ratio, h_ratio = map(int, aspect_ratio.split(":")) | |
| target_ratio = w_ratio / h_ratio | |
| # Ensure image is RGB | |
| 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": | |
| # Use Pillow's expand with white fill | |
| result = ImageOps.expand(image, border=padding, fill=(255, 255, 255)) | |
| else: | |
| # Use image filler (blurred border) | |
| result = image_filler(image, padding) | |
| # Resize to exact target size (optional, in case of rounding) | |
| result = result.resize((new_w, new_h), Image.LANCZOS) | |
| return result | |
| aspect_ratios = ["1:1", "4:3", "16:9", "3:2", "21:9", "9:16"] | |
| 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() | |