InvokeAI/invokeai/backend/image_util/util.py

72 lines
2.3 KiB
Python
Raw Normal View History

2023-03-03 06:02:00 +00:00
from math import ceil, floor, sqrt
from PIL import Image
2023-03-03 06:02:00 +00:00
class InitImageResizer:
"""Simple class to create resized copies of an Image while preserving the aspect ratio."""
2023-03-03 06:02:00 +00:00
def __init__(self, Image):
self.image = Image
2023-03-03 06:02:00 +00:00
def resize(self, width=None, height=None) -> Image:
"""
Return a copy of the image resized to fit within
a box width x height. The aspect ratio is
maintained. If neither width nor height are provided,
then returns a copy of the original image. If one or the other is
provided, then the other will be calculated from the
aspect ratio.
Everything is floored to the nearest multiple of 64 so
that it can be passed to img2img()
"""
2023-03-03 06:02:00 +00:00
im = self.image
2023-03-03 06:02:00 +00:00
ar = im.width / float(im.height)
# Infer missing values from aspect ratio
2023-03-03 06:02:00 +00:00
if not (width or height): # both missing
width = im.width
height = im.height
2023-03-03 06:02:00 +00:00
elif not height: # height missing
height = int(width / ar)
elif not width: # width missing
width = int(height * ar)
2023-03-03 06:02:00 +00:00
w_scale = width / im.width
h_scale = height / im.height
scale = min(w_scale, h_scale)
(rw, rh) = (int(scale * im.width), int(scale * im.height))
2023-03-03 06:02:00 +00:00
# round everything to multiples of 64
width, height, rw, rh = map(lambda x: x - x % 64, (width, height, rw, rh))
# no resize necessary, but return a copy
if im.width == width and im.height == height:
return im.copy()
# otherwise resize the original image so that it fits inside the bounding box
2023-03-03 06:02:00 +00:00
resized_image = self.image.resize((rw, rh), resample=Image.Resampling.LANCZOS)
return resized_image
2023-03-03 06:02:00 +00:00
2022-08-31 04:36:38 +00:00
def make_grid(image_list, rows=None, cols=None):
image_cnt = len(image_list)
if None in (rows, cols):
rows = floor(sqrt(image_cnt)) # try to make it square
cols = ceil(image_cnt / rows)
width = image_list[0].width
height = image_list[0].height
2023-03-03 06:02:00 +00:00
grid_img = Image.new("RGB", (width * cols, height * rows))
2022-08-31 04:36:38 +00:00
i = 0
for r in range(0, rows):
for c in range(0, cols):
if i >= len(image_list):
break
grid_img.paste(image_list[i], (c * width, r * height))
i = i + 1
return grid_img