Tryon-demo / preprocess.py
Davidscut's picture
Add ZeroGPU virtual try-on demo
d85819f
Raw
History Blame Contribute Delete
2.06 kB
from __future__ import annotations
from pathlib import Path
from typing import Iterable
from PIL import Image, ImageOps
def load_garment_images(file_paths) -> list[Image.Image]:
"""Load Gradio File outputs into RGB PIL images."""
if file_paths is None:
return []
if isinstance(file_paths, (str, Path)):
file_paths = [file_paths]
images: list[Image.Image] = []
for item in file_paths:
if item is None:
continue
path = item
if not isinstance(path, (str, Path)) and hasattr(path, "name"):
path = path.name
p = Path(path)
if not p.exists():
continue
with Image.open(p) as img:
images.append(ImageOps.exif_transpose(img).convert("RGB"))
return images
def normalize_pil_image(image: Image.Image | None) -> Image.Image | None:
if image is None:
return None
return ImageOps.exif_transpose(image).convert("RGB")
def resize_for_demo(image: Image.Image, max_side: int = 1024) -> Image.Image:
"""Downscale very large uploads while preserving aspect ratio."""
image = normalize_pil_image(image)
if image is None:
raise ValueError("image is required")
width, height = image.size
longest = max(width, height)
if longest <= max_side:
return image
scale = max_side / float(longest)
new_size = (max(1, int(width * scale)), max(1, int(height * scale)))
return image.resize(new_size, Image.Resampling.LANCZOS)
def clamp_primary_index(primary_garment_index: int, garment_count: int) -> int:
if garment_count <= 0:
raise ValueError("At least one garment reference image is required.")
return max(0, min(int(primary_garment_index), garment_count - 1))
def select_primary_garment(
garment_images: Iterable[Image.Image],
primary_garment_index: int,
) -> tuple[Image.Image, int, list[Image.Image]]:
images = list(garment_images)
index = clamp_primary_index(primary_garment_index, len(images))
return images[index], index, images