← All ivy-nodes
IVYXSTUDIO · IVY NODE
I

Image Processor

ivy.node.image-processor · v0.1.0

ivyx✓

Loads image bytes with Pillow and returns the loaded image with its width, height and format. The image is a handle for image-show or another image node in the same run.

#Pillow#Image Processing#BytesIO#Image Loading#Image Manipulation#Image Object#PIL#Data Stream

Inputs

FieldTypeDescription
bufferrequiredNot declaredImage bytes in a format Pillow reads (PNG, JPEG, …).

Outputs

FieldTypeDescription
image_processorrequiredNot declaredThe loaded image, for image-show and other image nodes.
widthrequiredintegerImage width in pixels.
heightrequiredintegerImage height in pixels.
formatrequiredstringThe format Pillow detected, such as PNG.

Source

python

# Input preparation
inp = __ivy_ctx__["nodes"][__ivy_node_id__]["input"]
buffer = inp["buffer"]

# Compute
from PIL import Image, UnidentifiedImageError
import io

class PillowImageProcessor:
    """
    A class to handle image operations using the Pillow library.
    """

    def __init__(self, buffer: io.BytesIO):
        """
        Initialize the PillowImageProcessor with a buffer containing image data.

        :param buffer: A BytesIO object containing the raw image data. 
                       This buffer should represent a valid image format (e.g., JPEG, PNG).
        :raises ValueError: If the buffer is empty.
        """
        if buffer.getbuffer().nbytes == 0:
            raise ValueError("Buffer is empty. Cannot load an image.")
        
        self.buffer = buffer
        self.image = None  # Placeholder for the loaded Pillow Image object.
        self.load_image()  # Automatically load the image when an instance is created.

    def load_image(self):
        """
        Load an image from the provided buffer into a Pillow Image object.

        This method resets the buffer pointer to the start of the stream
        and uses Pillow to load the image. The loaded image is stored in the
        `self.image` attribute.

        :raises UnidentifiedImageError: If the buffer does not contain valid image data.
        """
        try:
            self.buffer.seek(0)  # Reset the buffer pointer to the start.
            self.image = Image.open(self.buffer)
        except UnidentifiedImageError:
            raise ValueError("Buffer does not contain a valid image.")

    def get_image(self) -> Image.Image:
        """
        Get the loaded Pillow Image object.

        :return: The loaded Pillow Image object.
        :raises RuntimeError: If the image has not been loaded yet.
        """
        if self.image is None:
            raise RuntimeError("Image not loaded. Call load_image() first.")
        return self.image

image_processor = PillowImageProcessor(buffer=buffer)

# Output collection (runner reads __ivy_ctx__)
out = __ivy_ctx__["nodes"][__ivy_node_id__]["output"]
out["image_processor"] = image_processor
out["width"], out["height"] = image_processor.get_image().size
out["format"] = str(image_processor.get_image().format)

Tests

Requires: python:3.9, pillow

  • png-2x3

    A 2x3 PNG loads with its size and format.

  • empty-buffer

    An empty buffer is refused before Pillow is asked.