69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
from typing import Tuple
|
|
import math
|
|
|
|
from PIL import Image
|
|
|
|
if not hasattr(Image, 'Resampling'): # Pillow<9.0
|
|
Image.Resampling = Image
|
|
|
|
|
|
def resize(image: Image.Image, size: Tuple[int, int]):
|
|
return image.resize(size, resample=Image.Resampling.LANCZOS)
|
|
|
|
|
|
def get_rgb_image(image:Image.Image):
|
|
if image.mode not in ["RGB", "RGBA"]:
|
|
image = image.convert("RGBA") if "transparency" in image.info else image.convert("RGB")
|
|
if image.mode == "RGBA":
|
|
white = Image.new("RGBA", image.size, (255, 255, 255, 255))
|
|
white.alpha_composite(image)
|
|
image = white.convert("RGB")
|
|
return image
|
|
|
|
|
|
def resize_and_fill(image: Image.Image, size: Tuple[int, int], repeat_edge = True, fill_rgb:tuple[int,int,int] = (255, 255, 255)):
|
|
width, height = size
|
|
scale_w, scale_h = width / image.width, height / image.height
|
|
resized_w, resized_h = width, height
|
|
if scale_w < scale_h:
|
|
resized_h = image.height * resized_w // image.width
|
|
elif scale_h < scale_w:
|
|
resized_w = image.width * resized_h // image.height
|
|
|
|
resized = resize(image, (resized_w, resized_h))
|
|
if resized_w == width and resized_h == height:
|
|
return resized
|
|
|
|
if repeat_edge:
|
|
fill_l = math.floor((width - resized_w) / 2)
|
|
fill_r = width - resized_w - fill_l
|
|
fill_t = math.floor((height - resized_h) / 2)
|
|
fill_b = height - resized_h - fill_t
|
|
result = Image.new("RGB", (width, height))
|
|
result.paste(resized, (fill_l, fill_t))
|
|
if fill_t > 0:
|
|
result.paste(resized.resize((width, fill_t), box=(0, 0, width, 0)), (0, 0))
|
|
if fill_b > 0:
|
|
result.paste(
|
|
resized.resize(
|
|
(width, fill_b), box=(0, resized.height, width, resized.height)
|
|
),
|
|
(0, resized.height + fill_t),
|
|
)
|
|
if fill_l > 0:
|
|
result.paste(resized.resize((fill_l, height), box=(0, 0, 0, height)), (0, 0))
|
|
if fill_r > 0:
|
|
result.paste(
|
|
resized.resize(
|
|
(fill_r, height), box=(resized.width, 0, resized.width, height)
|
|
),
|
|
(resized.width + fill_l, 0),
|
|
)
|
|
return result
|
|
else:
|
|
result = Image.new("RGB", size, fill_rgb)
|
|
result.paste(resized, box=((width - resized_w) // 2, (height - resized_h) // 2))
|
|
return result.convert("RGB")
|
|
|
|
|