import gradio as gr import cv2 import numpy as np from PIL import Image import requests def hex_to_rgb(hex_code): # Remove the '#' symbol if present hex_code = hex_code.lstrip('#') # Convert the hex code to RGB return tuple(int(hex_code[i:i+2], 16) for i in (0, 2, 4)) def crop_image(image, crop_top_percentage, crop_bottom_percentage): height, width = image.shape[:2] # Calculate the number of pixels to crop from the top and bottom as a percentage of the image height crop_top = int(height * crop_top_percentage / 100) crop_bottom = int(height * crop_bottom_percentage / 100) # Crop the input image cropped_image = image[crop_top:height - crop_bottom, :] return cropped_image def resize_and_overlay_image(input_image, reduction_percentage, shift_percentage_lr, shift_percentage_ud, background_color, crop_top_percentage, crop_bottom_percentage): # Check if the input image is empty if input_image.size == 0: return None img = np.array(input_image) # Check if the image has shape information if img.ndim < 2: return None # Crop the input image cropped_img = crop_image(img, crop_top_percentage, crop_bottom_percentage) # Get the dimensions of the cropped image height, width = cropped_img.shape[:2] # Calculate the new dimensions based on the reduction percentage new_height = int(height * reduction_percentage / 100) new_width = int(width * reduction_percentage / 100) # Calculate the shift values as a percentage of the image dimensions shift_x = int(width * shift_percentage_lr / 100) shift_y = int(height * shift_percentage_ud / 100) # Create a new background image with the same dimensions as the input image and specified color background_rgb = hex_to_rgb(background_color) background_img = np.ones_like(img) * background_rgb # Resize the cropped image while maintaining aspect ratio aspect_ratio = width / height if new_width / new_height > aspect_ratio: resized_height = new_height resized_width = int(new_height * aspect_ratio) else: resized_width = new_width resized_height = int(new_width / aspect_ratio) resized_img = cv2.resize(cropped_img, (resized_width, resized_height)) # Calculate the position to overlay the resized image on the background image x = int((width - resized_width) / 2) + shift_x y = int((height - resized_height) / 2) + shift_y # Overlay the resized image on the background image background_img[y:y + resized_height, x:x + resized_width] = resized_img # Return the resulting image as a NumPy array return background_img # Create the Gradio interface iface = gr.Interface( fn=resize_and_overlay_image, inputs=[ gr.inputs.Image(type="pil", label="Input Image"), gr.inputs.Slider(minimum=30, maximum=100, step=5, default=80, label="Percentage of Original"), gr.inputs.Slider(minimum=-30, maximum=30, step=1, default=0, label="Shift Left / Right (%)"), gr.inputs.Slider(minimum=-30, maximum=30, step=1, default=0, label="Shift Up / Down (%)"), gr.inputs.Textbox(default="#ffffff", label="Background Color (Hex Code)"), gr.inputs.Slider(minimum=0, maximum=25, step=1, default=0, label="Crop Top (%)"), gr.inputs.Slider(minimum=0, maximum=25, step=1, default=0, label="Crop Bottom (%)") ], outputs=gr.outputs.Image(type="numpy", label="Result"), title="Image Resizer", description="Crop the input image, overlay it on a new background of the specified color, start centered, and shift it as a percentage without stretching." ) if __name__ == "__main__": iface.launch()