Image transformation, compression, and decompression codecs for scientific computing
—
Image-specific codecs for common formats including JPEG, PNG, TIFF, WebP, and next-generation formats like AVIF, HEIF, and JPEG XL. These codecs are optimized for photographic and graphic content, supporting various color spaces, bit depths, and compression modes.
Industry-standard lossy compression for photographic images with extensive configuration options and automatic fallback to lossless JPEG for high bit-depth content.
def jpeg_encode(data, level=None, *, colorspace=None, outcolorspace=None, subsampling=None, optimize=None, smoothing=None, out=None):
"""
Return JPEG encoded image with automatic LJPEG fallback for high bit-depth.
Parameters:
- data: NDArray - Image data to encode (2D grayscale or 3D RGB/RGBA)
- level: int | None - Quality level (0-100, default 75). Higher = better quality
- colorspace: str | None - Input color space ('rgb', 'ycbcr', 'cmyk', 'ycck')
- outcolorspace: str | None - Output color space for encoding
- subsampling: str | None - Chroma subsampling:
'444' = no subsampling, '422' = 2x1, '420' = 2x2, '411' = 4x1
- optimize: bool | None - Optimize Huffman tables (slower, better compression)
- smoothing: int | None - Smoothing factor (0-100)
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: JPEG encoded image data
"""
def jpeg_decode(data, *, tables=None, colorspace=None, outcolorspace=None, shape=None, out=None):
"""
Return decoded JPEG image with automatic LJPEG support.
Parameters:
- data: bytes | bytearray | mmap.mmap - JPEG encoded data
- tables: bytes | None - External Huffman/quantization tables
- colorspace: str | None - Expected input color space
- outcolorspace: str | None - Desired output color space
- shape: tuple | None - Expected output shape for validation
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def jpeg_check(data):
"""
Check if data is JPEG encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if JPEG SOI marker detected
"""Lossless compression with transparency support, ideal for graphics, screenshots, and images requiring exact pixel reproduction.
def png_encode(data, level=None, *, strategy=None, filter=None, out=None):
"""
Return PNG encoded image.
Parameters:
- data: NDArray - Image data (grayscale, RGB, or RGBA)
- level: int | None - Compression level (0-9, default 6)
- strategy: str | None - Compression strategy:
'default', 'filtered', 'huffman', 'rle', 'fixed'
- filter: str | None - Row filter type:
'none', 'sub', 'up', 'average', 'paeth', 'auto'
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: PNG encoded image data
"""
def png_decode(data, *, out=None):
"""
Return decoded PNG image.
Parameters:
- data: bytes | bytearray | mmap.mmap - PNG encoded data
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def png_check(data):
"""
Check if data is PNG encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if PNG signature detected
"""Modern image format supporting both lossy and lossless compression with superior efficiency compared to JPEG and PNG.
def webp_encode(data, level=None, *, lossless=None, method=None, out=None):
"""
Return WebP encoded image.
Parameters:
- data: NDArray - Image data (RGB or RGBA)
- level: int | None - Quality level (0-100 for lossy, 0-9 for lossless)
- lossless: bool | None - Use lossless compression (default False)
- method: int | None - Compression method (0-6, default 4). Higher = slower, better
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: WebP encoded image data
"""
def webp_decode(data, *, out=None):
"""
Return decoded WebP image.
Parameters:
- data: bytes | bytearray | mmap.mmap - WebP encoded data
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def webp_check(data):
"""
Check if data is WebP encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if WebP signature detected
"""Next-generation format based on AV1 video codec, providing excellent compression efficiency for both lossy and lossless modes.
def avif_encode(data, level=None, *, speed=None, tilelog2=None, bitspersample=None, pixelformat=None, codec=None, numthreads=None, out=None):
"""
Return AVIF encoded image.
Parameters:
- data: NDArray - Image data to encode
- level: int | None - Quality level (0-100, default 50). Higher = better quality
- speed: int | None - Encoding speed (0-10, default 6). Higher = faster, lower quality
- tilelog2: int | None - Tile size as log2 (0-6, default 0=no tiling)
- bitspersample: int | None - Bits per sample (8, 10, 12)
- pixelformat: str | None - Pixel format ('yuv420', 'yuv422', 'yuv444', 'yuv400')
- codec: str | None - AV1 codec implementation ('aom', 'rav1e', 'svt')
- numthreads: int | None - Number of encoding threads
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: AVIF encoded image data
"""
def avif_decode(data, index=None, *, numthreads=None, out=None):
"""
Return decoded AVIF image.
Parameters:
- data: bytes | bytearray | mmap.mmap - AVIF encoded data
- index: int | None - Image index for multi-image files (default 0)
- numthreads: int | None - Number of decoding threads
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def avif_check(data):
"""
Check if data is AVIF encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool | None: True if AVIF signature detected
"""Next-generation JPEG replacement with superior compression, wide bit-depth support, and advanced features.
def jpegxl_encode(data, level=None, *, effort=None, distance=None, lossless=None, decodingspeed=None, photometric=None, bitspersample=None, planar=None, usecontainer=None, numthreads=None, out=None):
"""
Return JPEG XL encoded image.
Parameters:
- data: NDArray - Image data to encode
- level: int | None - Quality level (0-100) for lossy mode
- effort: int | None - Encoding effort (1-9, default 7). Higher = slower, better compression
- distance: float | None - Psychovisual distance (0.0-25.0). Lower = better quality
- lossless: bool | None - Use lossless compression (default False)
- decodingspeed: int | None - Decoding speed tier (0-4, default 0)
- photometric: str | None - Color interpretation ('minisblack', 'rgb', 'ycbcr')
- bitspersample: int | None - Bits per sample (1-32, default based on input)
- planar: bool | None - Use planar pixel layout
- usecontainer: bool | None - Use JPEG XL container format
- numthreads: int | None - Number of encoding threads
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: JPEG XL encoded image data
"""
def jpegxl_decode(data, index=None, *, keeporientation=None, numthreads=None, out=None):
"""
Return decoded JPEG XL image.
Parameters:
- data: bytes | bytearray | mmap.mmap - JPEG XL encoded data
- index: int | None - Frame index for animated images (default 0)
- keeporientation: bool | None - Preserve EXIF orientation (default False)
- numthreads: int | None - Number of decoding threads
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def jpegxl_check(data):
"""
Check if data is JPEG XL encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if JPEG XL signature detected
"""Flexible Tagged Image File Format supporting multiple pages, various compression schemes, and extensive metadata.
def tiff_encode(data, *, compression=None, level=None, predictor=None, out=None):
"""
Return TIFF encoded image.
Parameters:
- data: NDArray - Image data (supports various dtypes and dimensionalities)
- compression: str | None - Compression scheme:
'none', 'lzw', 'jpeg', 'zlib', 'packbits', 'lzma', 'zstd', 'webp'
- level: int | None - Compression level (codec-dependent)
- predictor: int | None - Predictor for LZW/ZLIB (1=none, 2=horizontal, 3=floating-point)
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: TIFF encoded image data
"""
def tiff_decode(data, *, key=None, out=None):
"""
Return decoded TIFF image.
Parameters:
- data: bytes | bytearray | mmap.mmap - TIFF encoded data
- key: int | None - Page/directory index to decode (default 0)
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def tiff_check(data):
"""
Check if data is TIFF encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if TIFF signature detected
"""High Efficiency Image Format used by Apple devices and modern cameras for superior compression.
def heif_encode(data, level=None, *, bitspersample=None, photometric=None, out=None):
"""
Return HEIF encoded image.
Parameters:
- data: NDArray - Image data to encode
- level: int | None - Quality level (0-100, default 50)
- bitspersample: int | None - Bits per sample (8, 10, 12)
- photometric: str | None - Color interpretation ('rgb', 'ycbcr')
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: HEIF encoded image data
"""
def heif_decode(data, index=None, *, out=None):
"""
Return decoded HEIF image.
Parameters:
- data: bytes | bytearray | mmap.mmap - HEIF encoded data
- index: int | None - Image index for multi-image files (default 0)
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def heif_check(data):
"""
Check if data is HEIF encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if HEIF signature detected
"""Graphics Interchange Format with palette-based compression and animation support.
def gif_encode(data, *, interlace=None, out=None):
"""
Return GIF encoded image.
Parameters:
- data: NDArray - Image data (will be quantized to 256 colors)
- interlace: bool | None - Use interlaced encoding
- out: bytes | bytearray | None - Pre-allocated output buffer
Returns:
bytes | bytearray: GIF encoded image data
"""
def gif_decode(data, index=None, *, out=None):
"""
Return decoded GIF image.
Parameters:
- data: bytes | bytearray | mmap.mmap - GIF encoded data
- index: int | None - Frame index for animated GIFs (default 0)
- out: NDArray | None - Pre-allocated output buffer
Returns:
NDArray: Decoded image array
"""
def gif_check(data):
"""
Check if data is GIF encoded.
Parameters:
- data: bytes | bytearray | mmap.mmap - Data to check
Returns:
bool: True if GIF signature detected
"""import imagecodecs
import numpy as np
# Create test image
image = np.random.randint(0, 256, (512, 512, 3), dtype=np.uint8)
# Compare different formats at similar quality levels
jpeg_data = imagecodecs.jpeg_encode(image, level=85)
webp_data = imagecodecs.webp_encode(image, level=85)
avif_data = imagecodecs.avif_encode(image, level=85)
jpegxl_data = imagecodecs.jpegxl_encode(image, level=85)
print(f"Original size: {image.nbytes} bytes")
print(f"JPEG size: {len(jpeg_data)} bytes ({len(jpeg_data)/image.nbytes:.2%})")
print(f"WebP size: {len(webp_data)} bytes ({len(webp_data)/image.nbytes:.2%})")
print(f"AVIF size: {len(avif_data)} bytes ({len(avif_data)/image.nbytes:.2%})")
print(f"JPEG XL size: {len(jpegxl_data)} bytes ({len(jpegxl_data)/image.nbytes:.2%})")import imagecodecs
import numpy as np
# Graphics with sharp edges (better for lossless)
image = np.zeros((256, 256, 3), dtype=np.uint8)
image[50:200, 50:200] = [255, 0, 0] # Red square
image[100:150, 100:150] = [0, 255, 0] # Green square
# Lossless compression comparison
png_data = imagecodecs.png_encode(image, level=9)
webp_lossless = imagecodecs.webp_encode(image, lossless=True, level=9)
jpegxl_lossless = imagecodecs.jpegxl_encode(image, lossless=True, effort=9)
print(f"PNG size: {len(png_data)} bytes")
print(f"WebP lossless: {len(webp_lossless)} bytes")
print(f"JPEG XL lossless: {len(jpegxl_lossless)} bytes")
# Verify lossless reconstruction
png_decoded = imagecodecs.png_decode(png_data)
assert np.array_equal(image, png_decoded)import imagecodecs
import numpy as np
# Large high-resolution image
large_image = np.random.randint(0, 256, (4096, 4096, 3), dtype=np.uint8)
# Multi-threaded encoding for supported formats
avif_mt = imagecodecs.avif_encode(large_image, level=50, numthreads=8)
jpegxl_mt = imagecodecs.jpegxl_encode(large_image, level=50, numthreads=8)
print(f"Multi-threaded AVIF: {len(avif_mt)} bytes")
print(f"Multi-threaded JPEG XL: {len(jpegxl_mt)} bytes")import imagecodecs
import numpy as np
# Multi-page TIFF with different compression
pages = []
for i in range(5):
page = np.random.randint(0, 256, (256, 256), dtype=np.uint16)
pages.append(page)
# Encode each page with different compression
tiff_data = b""
for i, page in enumerate(pages):
compression = ['none', 'lzw', 'zlib', 'zstd', 'lzma'][i]
page_data = imagecodecs.tiff_encode(page, compression=compression)
if i == 0:
tiff_data = page_data
# Note: Multi-page TIFF requires specialized handling
# Read specific page
page_0 = imagecodecs.tiff_decode(tiff_data, key=0)class JpegError(Exception):
"""JPEG codec exception."""
class PngError(Exception):
"""PNG codec exception."""
class WebpError(Exception):
"""WebP codec exception."""
class AvifError(Exception):
"""AVIF codec exception."""
class JpegxlError(Exception):
"""JPEG XL codec exception."""
class TiffError(Exception):
"""TIFF codec exception."""
class HeifError(Exception):
"""HEIF codec exception."""
class GifError(Exception):
"""GIF codec exception."""Common error handling:
import imagecodecs
try:
encoded = imagecodecs.avif_encode(image, level=50)
except imagecodecs.DelayedImportError:
# AVIF codec not available, fallback to WebP
encoded = imagecodecs.webp_encode(image, level=85)
except imagecodecs.AvifError as e:
print(f"AVIF encoding failed: {e}")
# Handle encoding errorInstall with Tessl CLI
npx tessl i tessl/pypi-imagecodecs