File size: 2,064 Bytes
d85819f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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