from enum import Enum from PIL import Image class ResizeMode(Enum): RESIZE = 0 # just resize RESIZE_TO_FILL = 1 # crop and resize RESIZE_TO_FIT = 2 # resize and fill def resize_image(im: Image.Image, width: int, height: int, resize_mode=ResizeMode.RESIZE_TO_FIT): """ Resizes an image with the specified resize_mode, width, and height. Args: resize_mode: The mode to use when resizing the image. 0: Resize the image to the specified width and height. 1: Resize the image to fill the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, cropping the excess. 2: Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, filling empty with data from image. im: The image to resize. width: The width to resize the image to. height: The height to resize the image to. upscaler_name: The name of the upscaler to use. If not provided, defaults to opts.upscaler_for_img2img. """ def resize(im: Image.Image, w, h): return im.resize((w, h), resample=Image.LANCZOS) if resize_mode == ResizeMode.RESIZE: res = resize(im, width, height) elif resize_mode == ResizeMode.RESIZE_TO_FILL: ratio = width / height src_ratio = im.width / im.height src_w = width if ratio > src_ratio else im.width * height // im.height src_h = height if ratio <= src_ratio else im.height * width // im.width resized = resize(im, src_w, src_h) res = Image.new("RGB", (width, height)) res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2)) else: ratio = width / height src_ratio = im.width / im.height src_w = width if ratio < src_ratio else im.width * height // im.height src_h = height if ratio >= src_ratio else im.height * width // im.width resized = resize(im, src_w, src_h) res = Image.new("RGB", (width, height)) res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2)) if ratio < src_ratio: fill_height = height // 2 - src_h // 2 if fill_height > 0: res.paste(resized.resize((width, fill_height), box=(0, 0, width, 0)), box=(0, 0)) res.paste( resized.resize((width, fill_height), box=(0, resized.height, width, resized.height)), box=(0, fill_height + src_h), ) elif ratio > src_ratio: fill_width = width // 2 - src_w // 2 if fill_width > 0: res.paste(resized.resize((fill_width, height), box=(0, 0, 0, height)), box=(0, 0)) res.paste( resized.resize((fill_width, height), box=(resized.width, 0, resized.width, height)), box=(fill_width + src_w, 0), ) return res def flatten_image(im: Image.Image, bgcolor="#ffffff"): """replaces transparency with bgcolor (example: "#ffffff"), returning an RGB mode image with no transparency""" if im.mode == "RGBA": background = Image.new("RGBA", im.size, bgcolor) background.paste(im, mask=im) im = background return im.convert("RGB")