Skip to content

util

visualize.util

add_opacity_to_color_tuple

add_opacity_to_color_tuple(color: Optional[Tuple[int, int, int]] = None, opacity: float = 1.0) -> Optional[Tuple[int, int, int, int]]

Convert RGB color tuple to RGBA with specific opacity.

Parameters:

  • color (Tuple[int, int, int], default: None ) –

    Tuple of RGB color, each value has the range [0, 255]. Defaults to None.

  • opacity (float, default: 1.0 ) –

    Opacity value. Expected range is [0., 1.]. Defaults to 1..

Returns:

  • Optional[Tuple[int, int, int, int]]

    Tuple[int, int, int, int]: Converted RGBA color tuple.

Note

Since the PIL can handle outliers, this function does not separately check for outliers for RGBA tuple.

It is correct not to consider the case where color is None, (if it is None, should not to call this function), but in this function, It is more efficient to assume that color is None rather than handling all exceptions for None in the Visualize implementation. (By keeping the color Tuple as None, PIL can handle it automatically.)

Source code in SaigeToolkit/visualize/util.py
def add_opacity_to_color_tuple(
    color: Optional[Tuple[int, int, int]] = None,
    opacity: float = 1.0,
) -> Optional[Tuple[int, int, int, int]]:
    """Convert RGB color tuple to RGBA with specific opacity.

    Args:
        color (Tuple[int, int, int], optional): Tuple of RGB color,
            each value has the range [0, 255]. Defaults to None.
        opacity (float, optional): Opacity value.
            Expected range is [0., 1.]. Defaults to 1..

    Returns:
        Tuple[int, int, int, int]: Converted RGBA color tuple.

    Note:
        Since the `PIL` can handle outliers,
        this function does not separately check for outliers for RGBA tuple.

        It is correct not to consider the case where `color` is None,
        (if it is `None`, should not to call this function),
        but in this function, It is more efficient to assume that `color` is `None`
        rather than handling all exceptions for `None` in the `Visualize` implementation.
        (By keeping the `color` Tuple as None, `PIL` can handle it automatically.)

    """
    if color is None:
        return None

    return (*color, int(opacity * 255))

blend_layers

blend_layers(layers: List[Image]) -> Image

Blend multiple layers into one layer respect alpha channel.

Parameters:

  • layers (List[Image]) –

    Layers to blend. First element will place to bottom, and last one to top. If layer's mode is not 'RGBA', it will convert to 'RGBA' with opacity 1.0.

Returns:

  • Image

    Image.Image: Blended image.

Source code in SaigeToolkit/visualize/util.py
def blend_layers(
    layers: List[Image.Image],
) -> Image.Image:
    """Blend multiple layers into one layer respect alpha channel.

    Args:
        layers (List[Image.Image]): Layers to blend.
            First element will place to bottom, and last one to top.
            If layer's mode is not 'RGBA', it will convert to 'RGBA' with opacity 1.0.

    Returns:
        Image.Image: Blended image.

    """
    base_layer = get_empty_layer(layers[0].size)

    for layer in layers:
        if layer.mode != "RGBA":
            layer = layer.convert("RGBA")
        base_layer.paste(Image.alpha_composite(base_layer, layer))

    return base_layer

get_empty_layer

get_empty_layer(size: Tuple[int, int], color: Tuple[int, int, int] = (0, 0, 0), opacity: float = 0.0) -> Image

Create empty layer.

Parameters:

  • size (Tuple[int, int]) –

    (width, height) in pixels.

  • color (Tuple[int, int, int], default: (0, 0, 0) ) –

    Layer's base color (Background). Defaults to (0, 0, 0) (black).

  • opacity (float, default: 0.0 ) –

    Opacity value. Defaults to 0..

Returns:

  • Image

    Image.Image: Empty layer.

Source code in SaigeToolkit/visualize/util.py
def get_empty_layer(
    size: Tuple[int, int],
    color: Tuple[int, int, int] = (0, 0, 0),
    opacity: float = 0.0,
) -> Image.Image:
    """Create empty layer.

    Args:
        size (Tuple[int, int]): (width, height) in pixels.
        color (Tuple[int, int, int], optional): Layer's base color (Background).
            Defaults to (0, 0, 0) (black).
        opacity (float, optional): Opacity value. Defaults to 0..

    Returns:
        Image.Image: Empty layer.

    """
    return Image.new(mode="RGBA", size=size, color=(*color, int(opacity * 255)))

concatenate_images

concatenate_images(images: List[Image], mode: str = 'RGBA', orientation: str = 'horizontal') -> Image

Concatenates all images in a line.

Parameters:

  • images (List[Image]) –

    List of images to concatenate.

  • mode (str, default: 'RGBA' ) –

    Result image's mode. Defaults to "RGBA".

  • orientation (str, default: 'horizontal' ) –

    Determines the direction of concatenate. When orientation == "horizontal", all images must have the same height and when orientation == "vertical", all images must have the same width. Defaults to 'horizontal'.

Returns:

  • Image

    Image.Image: Concatenated image.

Source code in SaigeToolkit/visualize/util.py
def concatenate_images(
    images: List[Image.Image],
    mode: str = "RGBA",
    orientation: str = "horizontal",
) -> Image.Image:
    """Concatenates all images in a line.

    Args:
        images (List[Image.Image]): List of images to concatenate.
        mode (str, optional): Result image's mode. Defaults to "RGBA".
        orientation (str, optional): Determines the direction of concatenate.
            When `orientation == "horizontal"`, all images must have the same height
            and when `orientation == "vertical"`, all images must have the same width.
            Defaults to 'horizontal'.

    Returns:
        Image.Image: Concatenated image.

    """
    src = None
    for image in images:
        if src is None:
            src = image

        else:
            if orientation.lower() == "horizontal":
                dst = Image.new(mode, (src.width + image.width, max(src.height, image.height)))
                dst.paste(image, (src.width, 0))

            if orientation.lower() == "vertical":
                dst = Image.new(mode, (max(src.width, image.width), src.height + image.height))
                dst.paste(image, (0, src.height))

            dst.paste(src, (0, 0))
            src = dst

    return src

safety_visualize

safety_visualize(original_fn: callable) -> callable

Decorator for stable visualization.

Temporarily convert the canvas image mode to RGBA for visualize operation. After visualize is completed, converted back to the original image mode and returned.

Source code in SaigeToolkit/visualize/util.py
def safety_visualize(original_fn: callable) -> callable:
    """Decorator for stable visualization.

    Temporarily convert the canvas image mode to RGBA for visualize operation.
    After visualize is completed, converted back to the original image mode and returned."""

    def wrapper(canvas: Image.Image, *args, **kwargs):
        canvas_mode = canvas.mode

        if canvas_mode != "RGBA":
            canvas = canvas.convert("RGBA")

        return original_fn(canvas, *args, **kwargs).convert(canvas_mode)

    return wrapper