CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-imageio

Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.

Pending
Overview
Eval results
Files

reader-writer.mddocs/

Reader/Writer Objects

Low-level interfaces for manual control over reading and writing operations, providing fine-grained parameter access and custom workflow support.

Capabilities

Reader Objects

Get reader objects for manual, sequential, or custom reading workflows.

def get_reader(uri, format=None, mode="?", **kwargs):
    """
    Get a Reader object for manual reading operations.
    
    Parameters:
    - uri (ImageResource): File path, URL, bytes, or file object
    - format (str, optional): Format to use for reading
    - mode (str): Reader mode hint
        - 'i': single image
        - 'I': multiple images  
        - 'v': single volume
        - 'V': multiple volumes
        - '?': don't care (default)
    - **kwargs: Format-specific parameters
    
    Returns:
    - Reader: Reader object with manual control methods
    """

Usage Examples:

import imageio.v2 as imageio

# Basic reader usage
reader = imageio.get_reader('animation.gif')

try:
    print(f"Number of frames: {len(reader)}")
    print(f"Format: {reader.format}")
    
    # Read frames individually
    frame_0 = reader.get_data(0)
    frame_5 = reader.get_data(5)
    
    # Get metadata
    global_meta = reader.get_meta_data()
    frame_meta = reader.get_meta_data(3)
    
    # Iterate through frames
    for i, frame in enumerate(reader):
        print(f"Frame {i}: {frame.shape}")
        if i >= 10:  # Process first 10 frames only
            break

finally:
    reader.close()  # Always close reader

# Context manager usage (recommended)
with imageio.get_reader('video.mp4') as reader:
    print(f"Video length: {len(reader)} frames")
    
    # Skip frames efficiently
    for i in range(0, len(reader), 30):  # Every 30th frame
        frame = reader.get_data(i)
        process_frame(frame, i)  # Your processing function

Writer Objects

Get writer objects for manual, streaming, or custom writing workflows.

def get_writer(uri, format=None, mode="?", **kwargs):
    """
    Get a Writer object for manual writing operations.
    
    Parameters:
    - uri (ImageResource): Output path or file object
    - format (str, optional): Format to use for writing
    - mode (str): Writer mode hint
        - 'i': single image
        - 'I': multiple images
        - 'v': single volume  
        - 'V': multiple volumes
        - '?': don't care (default)
    - **kwargs: Format-specific parameters
    
    Returns:
    - Writer: Writer object with manual control methods
    """

Usage Examples:

import imageio.v2 as imageio
import numpy as np

# Create animation frame by frame
with imageio.get_writer('animation.gif', duration=0.5) as writer:
    for i in range(20):
        # Generate frame dynamically
        frame = np.zeros((100, 100, 3), dtype=np.uint8)
        
        # Create rotating pattern
        angle = i * 18  # degrees
        x = int(50 + 30 * np.cos(np.radians(angle)))
        y = int(50 + 30 * np.sin(np.radians(angle)))
        frame[y-5:y+5, x-5:x+5] = [255, 0, 0]  # Red dot
        
        writer.append_data(frame)
        
        # Optional: set per-frame metadata
        frame_meta = {'frame_time': i * 0.5}
        # Note: metadata support varies by format

# Write video with custom parameters
with imageio.get_writer('output.mp4', fps=30, codec='libx264') as writer:
    for frame_data in generate_frames():  # Your frame generator
        writer.append_data(frame_data)

# Manual writer control (not recommended for normal use)
writer = imageio.get_writer('manual.png')
try:
    # For single images, append_data writes the image
    image = np.random.randint(0, 255, (200, 200, 3), dtype=np.uint8)
    writer.append_data(image)
    
    # Set global metadata if supported
    try:
        writer.set_meta_data({'software': 'ImageIO Example'})
    except NotImplementedError:
        print("Format doesn't support metadata writing")
finally:
    writer.close()

Reader Methods and Properties

Core Reader Methods

class Reader:
    """Reader object for manual image reading control."""
    
    def get_length(self):
        """Get number of images in the file."""
    
    def get_data(self, index):
        """Get image data at specific index."""
    
    def get_next_data(self):
        """Get next image in sequence."""
    
    def get_meta_data(self, index=None):
        """Get metadata for image or global metadata."""
    
    def set_image_index(self, index):
        """Set current reading position."""
    
    def close(self):
        """Close the reader and free resources."""
    
    def iter_data(self):
        """Iterate over all images with metadata."""
    
    # Properties
    request: Request  # Request object with file info
    format: Format    # Format object (legacy plugins only)

Detailed Usage:

import imageio.v2 as imageio

with imageio.get_reader('multi_page.tiff') as reader:
    # Length and basic info
    total_images = reader.get_length()
    print(f"Total images: {total_images}")
    
    # Access request information
    print(f"Filename: {reader.request.filename}")
    print(f"File size: {reader.request.get_file().seek(0, 2)}")
    
    # Random access to images
    middle_image = reader.get_data(total_images // 2)
    last_image = reader.get_data(-1)  # Last image
    
    # Sequential reading with position control
    reader.set_image_index(10)  # Start from image 10
    for i in range(5):  # Read next 5 images
        image = reader.get_next_data()
        print(f"Image {10+i}: {image.shape}")
    
    # Metadata access
    global_meta = reader.get_meta_data()  # Global file metadata
    for i in range(min(3, total_images)):  # First 3 images
        image_meta = reader.get_meta_data(i)
        print(f"Image {i} metadata: {image_meta}")
    
    # Iteration with metadata
    for image_with_meta in reader.iter_data():
        print(f"Image shape: {image_with_meta.shape}")
        print(f"Metadata: {image_with_meta.meta}")

Writer Methods and Properties

Core Writer Methods

class Writer:
    """Writer object for manual image writing control."""
    
    def append_data(self, im, meta=None):
        """Add image data to output."""
    
    def set_meta_data(self, meta):
        """Set global metadata for output file."""
    
    def close(self):
        """Close writer and finalize output."""
    
    # Properties  
    request: Request  # Request object with file info
    format: Format    # Format object (legacy plugins only)

Detailed Usage:

import imageio.v2 as imageio
import numpy as np
from datetime import datetime

# Create multi-page TIFF with metadata
with imageio.get_writer('output.tiff', compression='lzw') as writer:
    # Set global metadata
    global_meta = {
        'software': 'ImageIO Python',
        'datetime': datetime.now().isoformat(),
        'description': 'Multi-page TIFF created with ImageIO'
    }
    
    try:
        writer.set_meta_data(global_meta)
    except NotImplementedError:
        print("This format doesn't support global metadata")
    
    # Add images with individual metadata
    for i in range(5):
        # Create test image
        image = np.random.randint(0, 255, (100, 100), dtype=np.uint8)
        
        # Per-image metadata
        image_meta = {
            'page_number': i,
            'timestamp': datetime.now().timestamp()
        }
        
        # Append image (metadata support varies by format)
        writer.append_data(image, meta=image_meta)
    
    print(f"Written to: {writer.request.filename}")

Advanced Reader/Writer Patterns

Streaming Large Files

Handle large files without loading everything into memory:

import imageio.v2 as imageio
import numpy as np

def process_large_video(input_path, output_path, processing_func):
    """Process large video file frame by frame."""
    
    with imageio.get_reader(input_path) as reader:
        # Get video properties
        total_frames = len(reader)
        first_frame = reader.get_data(0)
        height, width = first_frame.shape[:2]
        
        print(f"Processing {total_frames} frames of size {height}x{width}")
        
        # Reset to beginning
        reader.set_image_index(0)
        
        with imageio.get_writer(output_path, fps=30) as writer:
            for frame_num in range(total_frames):
                # Read frame
                frame = reader.get_data(frame_num)
                
                # Process frame
                processed_frame = processing_func(frame)
                
                # Write processed frame
                writer.append_data(processed_frame)
                
                # Progress indicator
                if frame_num % 100 == 0:
                    print(f"Processed {frame_num}/{total_frames} frames")

# Example processing function
def enhance_contrast(frame):
    """Simple contrast enhancement."""
    frame = frame.astype(np.float32)
    frame = (frame - frame.min()) / (frame.max() - frame.min()) * 255
    return frame.astype(np.uint8)

# Usage
process_large_video('input_video.mp4', 'enhanced_video.mp4', enhance_contrast)

Custom Format Handling

Handle files that need special parameter control:

import imageio.v2 as imageio

def read_scientific_data(file_path, calibration_params):
    """Read scientific data with custom calibration."""
    
    with imageio.get_reader(file_path, format='TIFF') as reader:
        # Get calibration from metadata if available
        global_meta = reader.get_meta_data()
        
        # Override with provided calibration
        pixel_size = calibration_params.get('pixel_size', 1.0)
        units = calibration_params.get('units', 'pixels')
        
        print(f"Reading {len(reader)} images with {pixel_size} {units}/pixel")
        
        calibrated_images = []
        for i in range(len(reader)):
            # Read raw image
            raw_image = reader.get_data(i)
            image_meta = reader.get_meta_data(i)
            
            # Apply calibration (example: convert to physical units)
            calibrated_image = raw_image * pixel_size
            
            # Attach enhanced metadata
            enhanced_meta = {
                **image_meta,
                'pixel_size': pixel_size,
                'units': units,
                'calibrated': True
            }
            
            # Create Array with metadata
            from imageio.core import Array
            calibrated_array = Array(calibrated_image)
            calibrated_array.meta = enhanced_meta
            
            calibrated_images.append(calibrated_array)
        
        return calibrated_images

# Usage
calibration = {'pixel_size': 0.1, 'units': 'micrometers'}
calibrated_data = read_scientific_data('microscopy.tiff', calibration)

Error Recovery and Validation

Robust file handling with error recovery:

import imageio.v2 as imageio
import numpy as np

def robust_multi_image_read(file_path, max_errors=5):
    """Read multi-image file with error recovery."""
    
    try:
        reader = imageio.get_reader(file_path)
    except Exception as e:
        print(f"Cannot open {file_path}: {e}")
        return []
    
    valid_images = []
    error_count = 0
    
    try:
        total_length = len(reader)
        print(f"Attempting to read {total_length} images")
        
        for i in range(total_length):
            try:
                # Attempt to read image
                image = reader.get_data(i)
                
                # Validate image
                if image.size == 0:
                    raise ValueError("Empty image")
                
                if not np.isfinite(image).all():
                    raise ValueError("Invalid pixel values")
                
                valid_images.append(image)
                
            except Exception as e:
                error_count += 1
                print(f"Error reading image {i}: {e}")
                
                if error_count >= max_errors:
                    print(f"Too many errors ({error_count}), stopping")
                    break
                
                # Continue with next image
                continue
    
    finally:
        reader.close()
    
    print(f"Successfully read {len(valid_images)} images with {error_count} errors")
    return valid_images

# Usage
images = robust_multi_image_read('potentially_corrupted.tiff', max_errors=10)

Install with Tessl CLI

npx tessl i tessl/pypi-imageio

docs

formats-plugins.md

image-io.md

index.md

multi-image.md

reader-writer.md

v3-api.md

volume-data.md

tile.json