File size: 2,970 Bytes
8fdc036 |
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
from __future__ import annotations
from pathlib import Path
from typing import Literal
import numpy as np
import PIL.Image
from gradio import processing_utils
PIL.Image.init() # fixes https://github.com/gradio-app/gradio/issues/2843 (remove when requiring Pillow 9.4+)
def format_image(
im: PIL.Image.Image | None,
type: Literal["numpy", "pil", "filepath"],
cache_dir: str,
name: str = "image",
format: str = "webp",
) -> np.ndarray | PIL.Image.Image | str | None:
"""Helper method to format an image based on self.type"""
if im is None:
return im
if type == "pil":
return im
elif type == "numpy":
return np.array(im)
elif type == "filepath":
try:
path = processing_utils.save_pil_to_cache(
im, cache_dir=cache_dir, name=name, format=format
)
# Catch error if format is not supported by PIL
except (KeyError, ValueError):
path = processing_utils.save_pil_to_cache(
im,
cache_dir=cache_dir,
name=name,
format="png", # type: ignore
)
return path
else:
raise ValueError(
"Unknown type: "
+ str(type)
+ ". Please choose from: 'numpy', 'pil', 'filepath'."
)
def save_image(
y: np.ndarray | PIL.Image.Image | str | Path, cache_dir: str, format: str = "webp"
):
if isinstance(y, np.ndarray):
path = processing_utils.save_img_array_to_cache(
y, cache_dir=cache_dir, format=format
)
elif isinstance(y, PIL.Image.Image):
try:
path = processing_utils.save_pil_to_cache(
y, cache_dir=cache_dir, format=format
)
# Catch error if format is not supported by PIL
except (KeyError, ValueError):
path = processing_utils.save_pil_to_cache(
y, cache_dir=cache_dir, format="png"
)
elif isinstance(y, Path):
path = str(y)
elif isinstance(y, str):
path = y
else:
raise ValueError(
"Cannot process this value as an Image, it is of type: " + str(type(y))
)
return path
def crop_scale(img: PIL.Image.Image, final_width: int, final_height: int):
original_width, original_height = img.size
target_aspect_ratio = final_width / final_height
if original_width / original_height > target_aspect_ratio:
crop_height = original_height
crop_width = crop_height * target_aspect_ratio
else:
crop_width = original_width
crop_height = crop_width / target_aspect_ratio
left = (original_width - crop_width) / 2
top = (original_height - crop_height) / 2
img_cropped = img.crop(
(int(left), int(top), int(left + crop_width), int(top + crop_height))
)
img_resized = img_cropped.resize((final_width, final_height))
return img_resized
|