Source code for arsenal.image

import base64
import io
from typing import List
from typing import Optional
from typing import Tuple

import numpy as np
from arsenal.collections import intersperse
from PIL import Image

_default_sep_color = (100, 100, 100)  # RGB (0-255)
Color = Tuple[int, int, int]


[docs]def resize_image( image: np.ndarray, *, height: Optional[int] = None, width: Optional[int] = None, resample=Image.NEAREST, ) -> np.ndarray: """Resize image.""" if height is None and width is None: raise ValueError("At least one of width and height should be provided") img_height, img_width = image.shape[:-1] if height is None: height = int(width * img_height / img_width) if width is None: width = int(height * img_width / img_height) # image shape (H, W, 3) return np.array(Image.fromarray(image).resize((width, height), resample=resample))
[docs]def vstack_with_sep( rows: List[np.ndarray], sep_width: int = 3, sep_color: Color = _default_sep_color, **kwargs, ) -> np.ndarray: """Stack images on-top of one another with separator""" assert len(rows) > 0 sep = np.ones((sep_width, rows[0].shape[1], 3), dtype=np.uint8) sep[:, :] *= np.array(sep_color, dtype=np.uint8) return np.vstack(intersperse(rows, sep, **kwargs))
[docs]def hstack_with_sep( cols: List[np.ndarray], sep_width: int = 3, sep_color: Color = _default_sep_color, **kwargs, ) -> np.ndarray: """Stack images side-by-side with separator""" assert len(cols) > 0 sep = np.ones((cols[0].shape[0], sep_width, 3), dtype=np.uint8) sep[:, :] *= np.array(sep_color, dtype=np.uint8) return np.hstack(intersperse(cols, sep, **kwargs))
[docs]def img_to_base64(img: Image.Image) -> str: """Encode image to base64 encoded JPEG""" img = Image.fromarray(img) with io.BytesIO() as f: img.save(f, format="jpeg") return base64.b64encode(f.getvalue()).decode("ascii")
[docs]def base64_to_img(b64_img: str) -> Image.Image: """Decode base64 encoded image.""" return Image.open(io.BytesIO(base64.b64decode(b64_img)))