File size: 1,814 Bytes
15d68eb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | """Image utilities for Indic Heritage Studio v2."""
from __future__ import annotations
from pathlib import Path
from typing import Tuple, Union
import numpy as np
from PIL import Image
def load_image(path: Union[str, Path]) -> Image.Image:
"""Load an image as RGB PIL."""
img = Image.open(path)
if img.mode != "RGB":
img = img.convert("RGB")
return img
def resize_to_sdxl(image: Image.Image, target: int = 1024) -> Image.Image:
"""Resize so the longer edge = target, preserve aspect ratio."""
w, h = image.size
if w >= h:
new_w, new_h = target, int(h * target / w)
else:
new_w, new_h = int(w * target / h), target
return image.resize((new_w, new_h), Image.LANCZOS)
def center_crop_to(image: Image.Image, size: Tuple[int, int]) -> Image.Image:
"""Center-crop an image to exact dimensions."""
w, h = image.size
tw, th = size
left = (w - tw) // 2
top = (h - th) // 2
return image.crop((left, top, left + tw, top + th))
def image_to_numpy(image: Image.Image) -> np.ndarray:
return np.array(image.convert("RGB"))
def numpy_to_image(arr: np.ndarray) -> Image.Image:
return Image.fromarray(arr.astype(np.uint8))
def save_grid(images, path: Union[str, Path], cols: int = 4, cell_size: int = 256) -> None:
"""Save a list of images as a grid PNG."""
from PIL import Image as PILImage
n = len(images)
rows = (n + cols - 1) // cols
grid = PILImage.new("RGB", (cols * cell_size, rows * cell_size), color="white")
for i, img in enumerate(images):
r, c = i // cols, i % cols
img_resized = img.resize((cell_size, cell_size), PILImage.LANCZOS)
grid.paste(img_resized, (c * cell_size, r * cell_size))
Path(path).parent.mkdir(parents=True, exist_ok=True)
grid.save(path)
|