API Reference

This page documents the complete API of the puhu library.

Core Functions

puhu.open(fp)

Open and identify an image file or bytes.

Parameters:

fp (str or Path or bytes) – A filename (string), pathlib.Path object, or file object, or bytes

Returns:

An Image object

Return type:

Image

Raises:

IOError – If the file cannot be opened or identified

Example:

img = puhu.open("photo.jpg")
img = puhu.open(Path("photo.jpg"))

with open("photo.jpg", "rb") as f:
    img = puhu.open(f.read())
puhu.new(mode, size, color=None)

Create a new image with the given mode and size.

Parameters:
  • mode (str) – The mode to use for the new image. See Image Modes.

  • size (tuple[int, int]) – A 2-tuple containing (width, height) in pixels

  • color (str or tuple or int or None) – The color to use for the image. Default is black. Can be a color name, RGB tuple, or integer for grayscale.

Returns:

An Image object

Return type:

Image

Example:

# Black image
img = puhu.new("RGB", (800, 600))

# Red image
img = puhu.new("RGB", (800, 600), "red")
img = puhu.new("RGB", (800, 600), (255, 0, 0))

# Gray image
img = puhu.new("L", (800, 600), 128)

Image Class

class Image

Represents an image object in puhu.

Properties

width: int

The width of the image in pixels.

height: int

The height of the image in pixels.

size: tuple[int, int]

The size of the image as a 2-tuple (width, height).

mode: str

The image mode. See Image Modes for available modes.

format: str or None

The file format of the source file (e.g., “JPEG”, “PNG”), or None if the image was not loaded from a file.

Methods

resize(size, resample=Resampling.BILINEAR)

Returns a resized copy of this image.

Parameters:
  • size (tuple[int, int]) – The requested size in pixels as a 2-tuple (width, height)

  • resample (Resampling) – The resampling filter. One of Resampling values.

Returns:

A new Image object

Return type:

Image

Example:

resized = img.resize((800, 600))
resized = img.resize((400, 300), resample=puhu.Resampling.BICUBIC)
crop(box)

Returns a rectangular region from this image.

Parameters:

box (tuple[int, int, int, int]) – The crop rectangle as a 4-tuple (left, top, right, bottom)

Returns:

A new Image object

Return type:

Image

Raises:

ValueError – If the crop box is invalid or out of bounds

Example:

cropped = img.crop((100, 100, 500, 400))
rotate(angle)

Returns a rotated copy of this image.

Parameters:

angle (int) – The rotation angle in degrees. Only 90, 180, and 270 are supported.

Returns:

A new Image object

Return type:

Image

Raises:

ValueError – If the angle is not 90, 180, or 270

Example:

rotated = img.rotate(90)
transpose(method)

Returns a flipped or transposed copy of this image.

Parameters:

method (Transpose) – One of Transpose values

Returns:

A new Image object

Return type:

Image

Example:

flipped = img.transpose(puhu.Transpose.FLIP_LEFT_RIGHT)
mirrored = img.transpose(puhu.Transpose.FLIP_TOP_BOTTOM)
copy()

Returns a copy of this image.

Returns:

A new Image object

Return type:

Image

Example:

img_copy = img.copy()
split()

Split this image into individual bands.

Returns a tuple of L-mode (grayscale) images, one per channel. For a single-band image (mode "L"), the tuple contains a copy of the image with its mode preserved.

All returned images are independent copies — modifying one band does not affect the original or other bands.

Matches Pillow’s Image.split() exactly.

Returns:

A tuple of Image objects, one per band

Return type:

tuple[Image, …]

Example:

# Split an RGB image into R, G, B channels
img = puhu.open("photo.jpg")  # mode = "RGB"
r, g, b = img.split()

# Split an RGBA image
img = puhu.open("photo.png")  # mode = "RGBA"
r, g, b, a = img.split()

# Recombine channels (e.g. boost red)
import puhu
r_boosted = puhu.Image.new("L", img.size, 255)
out = puhu.merge("RGB", (r_boosted, g, b))
getbands()

Return a tuple containing the name of each band in the image.

Returns:

A tuple of band name strings

Return type:

tuple[str, …]

Example:

img = puhu.Image.new("RGB", (100, 100))
img.getbands()   # ('R', 'G', 'B')

img = puhu.Image.new("RGBA", (100, 100))
img.getbands()   # ('R', 'G', 'B', 'A')

img = puhu.Image.new("LA", (100, 100))
img.getbands()   # ('L', 'A')
thumbnail(size)

Modifies this image to contain a thumbnail version of itself, no larger than the given size. This method modifies the image in place.

Parameters:

size (tuple[int, int]) – The maximum size as a 2-tuple (width, height)

Example:

img.thumbnail((200, 200))
paste(im, box=None, mask=None)

Pastes another image or color into this image.

The box argument specifies where to paste:

  • None: Paste at (0, 0)

  • 2-tuple (x, y): Upper left corner. Supports negative values for clipping.

  • 4-tuple (left, upper, right, lower): Exact region (source size must match)

If the modes don’t match, the pasted image is automatically converted.

Parameters:
  • im (Image or tuple or int or str) – Source image, color tuple (RGB/RGBA), single integer (grayscale), or color string

  • box (tuple[int, int] or tuple[int, int, int, int] or None) – Where to paste. 2-tuple for position, 4-tuple for exact region, or None for (0, 0)

  • mask (Image or None) – Optional mask image (“L” or “1” mode). Where mask is 255, source is copied fully.

Example:

# Paste image at position
bg.paste(fg, (100, 100))

# Paste with negative coords (clips source)
bg.paste(fg, (-10, -10))

# Fill region with color
img.paste((255, 0, 0), (0, 0, 100, 100))
img.paste("red", (0, 0, 100, 100))

# Paste with mask
bg.paste(fg, (0, 0), mask)

# Abbreviated syntax: paste(im, mask)
bg.paste(fg, mask)
save(fp, format=None)

Saves this image to the specified file.

Parameters:
  • fp (str or Path) – A filename (string) or pathlib.Path object

  • format (str or None) – Optional format override. If not specified, format is determined from the file extension.

Raises:

IOError – If the file cannot be written

Example:

img.save("output.png")
img.save("output.jpg", format="JPEG")
to_bytes()

Returns the raw pixel data of the image as bytes.

Returns:

Raw pixel data

Return type:

bytes

Example:

pixel_data = img.to_bytes()

Enums and Constants

Image Modes

Puhu supports the following image modes:

  • “1”: 1-bit pixels, black and white

  • “L”: 8-bit pixels, grayscale

  • “LA”: 8-bit pixels, grayscale with alpha

  • “RGB”: 3x8-bit pixels, true color

  • “RGBA”: 4x8-bit pixels, true color with transparency

class Resampling

An enumeration of resampling filters for the Image.resize() method.

NEAREST = 0

Nearest neighbor resampling. Fastest, lowest quality.

BILINEAR = 2

Bilinear resampling. Good balance of speed and quality (default).

BICUBIC = 3

Bicubic resampling. High quality, slower than bilinear.

class Transpose

An enumeration of transpose/flip operations for the Image.transpose() method.

FLIP_LEFT_RIGHT

Flip the image horizontally (left to right).

FLIP_TOP_BOTTOM

Flip the image vertically (top to bottom).

Supported Formats

Input Formats

Puhu can read the following image formats:

  • PNG: Portable Network Graphics

  • JPEG: Joint Photographic Experts Group

  • BMP: Windows Bitmap

  • TIFF: Tagged Image File Format

  • GIF: Graphics Interchange Format

  • WEBP: WebP format

Output Formats

Puhu can write the following image formats:

  • PNG: Portable Network Graphics (lossless)

  • JPEG: Joint Photographic Experts Group (lossy)

  • BMP: Windows Bitmap (lossless)

  • TIFF: Tagged Image File Format (lossless)

  • GIF: Graphics Interchange Format (lossless)

  • WEBP: WebP format (lossy and lossless)

Exceptions

exception IOError

Raised when an image file cannot be opened, identified, or saved.

exception ValueError

Raised when invalid parameters are provided to image operations (e.g., invalid crop bounds, unsupported rotation angle).

Examples

Complete Workflow

import puhu

# Open image
img = puhu.open("input.jpg")

# Check properties
print(f"Size: {img.size}")
print(f"Mode: {img.mode}")
print(f"Format: {img.format}")

# Process image
img = img.resize((1920, 1080))
img = img.crop((0, 0, 1920, 1000))
img = img.rotate(90)

# Save result
img.save("output.png")

Batch Processing

import puhu
from pathlib import Path

input_dir = Path("input_images")
output_dir = Path("output_images")
output_dir.mkdir(exist_ok=True)

for img_path in input_dir.glob("*.jpg"):
    img = puhu.open(img_path)

    # Create thumbnail
    thumb = img.copy()
    thumb.thumbnail((300, 300))

    # Save thumbnail
    output_path = output_dir / f"{img_path.stem}_thumb.png"
    thumb.save(output_path)

    print(f"Processed {img_path.name}")