Skip to main content

Python bindings for libheif - HEIC/AVIF/JPEG2000 image codec

Project description

pylibheif

PyPI version Build and Publish License: LGPL v3 Python 3.11+

Python bindings for libheif using nanobind.

Features

  • HEIC/HEIF Support: Read and write HEIC images (HEVC/H.265 encoded)
  • AVIF Support: Read and write AVIF images (AV1 encoded)
  • JPEG2000 Support: Read and write JPEG2000 images in HEIF container
  • NumPy Integration: Zero-copy access to image data via Python Buffer Protocol
  • Metadata Support: Read and write EXIF, XMP, and custom metadata
  • HDR Metadata Support: Read and write HDR metadata (CLLI, MDCV, AMVE) using physical units (Nits, Lux, CIE coordinates) with type safety
  • Asynchronous Support: Built-in asyncio wrappers for non-blocking I/O and encoding
  • RAII Resource Management: Automatic resource cleanup with context managers

Supported Formats

Format Decoding Encoding Codec
HEIC (HEVC/H.265) libde265 (Dec) / x265 (Enc) / Kvazaar (Enc)
AVIF (AV1) DAV1D (Dec) / AOM (Enc)
JPEG2000 OpenJPEG
JPEG libjpeg

Requirements

  • Python >= 3.11
  • NumPy >= 1.26.0
  • CMake >= 3.15
  • C++17 compatible compiler

Installation

pip install pylibheif

Or with uv:

uv pip install pylibheif

Building from Source

# Clone with submodules
git clone --recursive https://github.com/twn39/pylibheif.git
cd pylibheif

# Install
uv pip install -e .

Usage

Reading HEIC/AVIF Images

Using context manager (recommended):

import pylibheif
import numpy as np

# Open HEIC file with context manager
with pylibheif.HeifContext() as ctx:
    ctx.read_from_file('image.heic')
    
    # Get primary image handle
    handle = ctx.get_primary_image_handle()
    print(f'Image size: {handle.width}x{handle.height}')
    print(f'Has alpha: {handle.has_alpha}')
    
    # Decode to RGB
    img = handle.decode(pylibheif.HeifColorspace.RGB, 
                        pylibheif.HeifChroma.InterleavedRGB)
    
    # Get as NumPy array (zero-copy)
    arr = img.get_plane(pylibheif.HeifChannel.Interleaved, False)  # shape: (height, width, 3)

Explicit creation (for more control):

import pylibheif
import numpy as np

# Create context explicitly
ctx = pylibheif.HeifContext()
ctx.read_from_file('image.heic')

handle = ctx.get_primary_image_handle()
img = handle.decode(pylibheif.HeifColorspace.RGB, 
                    pylibheif.HeifChroma.InterleavedRGB)
arr = img.get_plane(pylibheif.HeifChannel.Interleaved, False)

# Resources are automatically freed when objects go out of scope

Writing HEIC Images (H.265)

import pylibheif
import numpy as np

# Create image from NumPy array
width, height = 1920, 1080
img = pylibheif.HeifImage(width, height, 
                          pylibheif.HeifColorspace.RGB,
                          pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)

# Fill with data
arr = img.get_plane(pylibheif.HeifChannel.Interleaved, True)
arr[:] = your_image_data  # your RGB data

# Encode and save as HEIC
ctx = pylibheif.HeifContext()
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.HEVC)
encoder.set_lossy_quality(85)
encoder.encode_image(ctx, img)

ctx.write_to_file('output.heic')

Writing AVIF Images (AV1)

import pylibheif
import numpy as np

# Prepare image (same as above)
width, height = 1920, 1080
img = pylibheif.HeifImage(width, height, 
                          pylibheif.HeifColorspace.RGB,
                          pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)

# Encode and save as AVIF
ctx = pylibheif.HeifContext()

# Use AV1 format for AVIF
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.AV1)
encoder.set_lossy_quality(85)
encoder.set_parameter("speed", "6") # Optional: Tune speed (0-9)

encoder.encode_image(ctx, img)

# Save with .avif extension
ctx.write_to_file('output.avif')

Writing JPEG Images

import pylibheif
import numpy as np

# Prepare image (same as above)
width, height = 1920, 1080
img = pylibheif.HeifImage(width, height, 
                          pylibheif.HeifColorspace.RGB,
                          pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)

# Encode and save as JPEG
ctx = pylibheif.HeifContext()

# Use JPEG format
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.JPEG)
encoder.set_lossy_quality(90) # Quality 0-100

encoder.encode_image(ctx, img)

# Save with .jpg extension
ctx.write_to_file('output.jpg')

Writing JPEG2000 Images

import pylibheif
import numpy as np

# Prepare image (same as above)
width, height = 1920, 1080
img = pylibheif.HeifImage(width, height, 
                          pylibheif.HeifColorspace.RGB,
                          pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)

# Encode and save as JPEG2000 in HEIF container
ctx = pylibheif.HeifContext()

# Use JPEG2000 format
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.JPEG2000)
encoder.set_lossy_quality(85) # Quality 0-100

encoder.encode_image(ctx, img)

# Save with .jp2 or .heif extension
# Note: libheif typically saves JPEG2000 in a HEIF container
ctx.write_to_file('output.heif')

Encoder Selection

By default, pylibheif selects the best available encoder for the requested format (e.g. x265 for HEVC). You can also explicitly select a specific encoder (e.g. Kvazaar) if available.

import pylibheif

# 1. Get all available HEVC encoders
descriptors = pylibheif.get_encoder_descriptors(pylibheif.HeifCompressionFormat.HEVC)

# Print available encoders
for d in descriptors:
    print(f"ID: {d.id_name}, Name: {d.name}")

# 2. Find specific encoder (e.g. Kvazaar)
kvazaar_desc = next((d for d in descriptors if "kvazaar" in d.id_name), None)

if kvazaar_desc:
    # 3. Create encoder explicitly using the descriptor
    encoder = pylibheif.HeifEncoder(kvazaar_desc)
    
    # Verify which encoder is used
    print(f"Using encoder: {encoder.name}")
    
    encoder.set_lossy_quality(85)
    # encoder.encode_image(...)
    # encoder.encode_image(...)

Reading Metadata

import pylibheif

ctx = pylibheif.HeifContext()
ctx.read_from_file('image.heic')
handle = ctx.get_primary_image_handle()

# Get metadata block IDs
exif_ids = handle.get_metadata_block_ids('Exif')
for id in exif_ids:
    metadata_type = handle.get_metadata_block_type(id)
    metadata_bytes = handle.get_metadata_block(id)
    print(f'Metadata type: {metadata_type}, size: {len(metadata_bytes)}')

Writing Metadata

import pylibheif
import numpy as np

# Create and encode an image
width, height = 64, 64
img = pylibheif.HeifImage(width, height,
                          pylibheif.HeifColorspace.RGB,
                          pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)
arr = img.get_plane(pylibheif.HeifChannel.Interleaved, True)
arr[:] = 128  # fill with gray

ctx = pylibheif.HeifContext()
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.HEVC)
encoder.set_lossy_quality(85)
handle = encoder.encode_image(ctx, img)

# Add EXIF metadata (with 4-byte offset prefix for TIFF header)
exif_data = b'\x00\x00\x00\x00' + b'Exif\x00\x00' + b'II*\x00...'  # your EXIF data
ctx.add_exif_metadata(handle, exif_data)

# Add XMP metadata
xmp_data = b'''<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
      <dc:creator>My App</dc:creator>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>'''
ctx.add_xmp_metadata(handle, xmp_data)

# Add custom/generic metadata
custom_data = b'{"app": "myapp", "version": "1.0"}'
ctx.add_generic_metadata(handle, custom_data, "json", "application/json")

# Save
ctx.write_to_file('output_with_metadata.heic')

HDR Metadata

pylibheif supports reading and writing standard HDR metadata introduced in libheif 1.23.0:

  • Content Light Level (CLLI): MaxCLL (Max Content Light Level) and MaxFALL (Max Frame Average Light Level) in nits.
  • Mastering Display Colour Volume (MDCV): Mastering display primaries (Red, Green, Blue, White point) in CIE xy coordinates, and luminance range in nits.
  • Ambient Viewing Environment (AMVE): Ambient illumination in lux, and ambient light CIE xy coordinates.

The API exposes these values using standard float coordinates and physical units. It automatically handles the underlying fixed-point scaling and Annex E array index mapping (e.g. green-blue-red ordering in MDCV).

Reading HDR Metadata

You can query and retrieve HDR metadata from HeifImageHandle (or AsyncHeifImageHandle):

import pylibheif

with pylibheif.HeifContext() as ctx:
    ctx.read_from_file('hdr_image.heic')
    handle = ctx.get_primary_image_handle()
    
    # 1. Content Light Level (CLLI)
    if handle.has_content_light_level:
        cll = handle.content_light_level
        print(f"MaxCLL: {cll.max_content_light_level} nits")
        print(f"MaxFALL: {cll.max_pic_average_light_level} nits")
        
    # 2. Mastering Display Colour Volume (MDCV)
    if handle.has_mastering_display_colour_volume:
        mdcv = handle.mastering_display_colour_volume
        print(f"Red Primary: {mdcv.red_primary}")        # e.g., (0.680, 0.320)
        print(f"Green Primary: {mdcv.green_primary}")    # e.g., (0.265, 0.690)
        print(f"Blue Primary: {mdcv.blue_primary}")      # e.g., (0.150, 0.060)
        print(f"White Point: {mdcv.white_point}")        # e.g., (0.3127, 0.3290)
        print(f"Luminance Range: {mdcv.min_luminance} to {mdcv.max_luminance} nits")
        
    # 3. Ambient Viewing Environment (AMVE)
    if handle.has_ambient_viewing_environment:
        amve = handle.ambient_viewing_environment
        print(f"Ambient Illumination: {amve.ambient_illumination} lux")
        print(f"Ambient Light: {amve.ambient_light}")

Writing HDR Metadata

You can attach HDR metadata to HeifImage prior to encoding:

import pylibheif
import numpy as np

# Prepare image
img = pylibheif.HeifImage(64, 64, pylibheif.HeifColorspace.RGB, pylibheif.HeifChroma.InterleavedRGB)
img.add_plane(pylibheif.HeifChannel.Interleaved, 64, 64, 8)
arr = img.get_plane(pylibheif.HeifChannel.Interleaved, True)
arr[:] = 128  # Fill with gray

# 1. Set CLLI
img.content_light_level = pylibheif.HeifContentLightLevel(
    max_content_light_level=1000,
    max_pic_average_light_level=400
)

# 2. Set MDCV (mastering display characteristics)
img.mastering_display_colour_volume = pylibheif.HeifMasteringDisplayColourVolume(
    red_primary=(0.680, 0.320),
    green_primary=(0.265, 0.690),
    blue_primary=(0.150, 0.060),
    white_point=(0.3127, 0.3290),
    max_luminance=1000.0,
    min_luminance=0.005
)

# 3. Set AMVE
img.ambient_viewing_environment = pylibheif.HeifAmbientViewingEnvironment(
    ambient_illumination=315.5,
    ambient_light=(0.3127, 0.3290)
)

# Encode
ctx = pylibheif.HeifContext()
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.HEVC)
encoder.encode_image(ctx, img)
ctx.write_to_file('hdr_output.heic')

Asynchronous Support (asyncio)

pylibheif provides asynchronous wrappers for non-blocking I/O and CPU-intensive operations (like encoding and decoding) using asyncio.to_thread.

Async Reading and Decoding

import pylibheif
import asyncio
import numpy as np

async def read_async():
    # Recommended: Use 'async with' context manager
    async with pylibheif.AsyncHeifContext() as ctx:
        await ctx.read_from_file('image.heic')
        
        handle = ctx.get_primary_image_handle()
        
        # Asynchronously decode (offloaded to thread)
        img = await handle.decode(pylibheif.HeifColorspace.RGB, 
                                  pylibheif.HeifChroma.InterleavedRGB)
        
        arr = img.get_plane(pylibheif.HeifChannel.Interleaved, False)
        return arr

asyncio.run(read_async())

Async Encoding and Writing

import pylibheif
import asyncio
import numpy as np

async def write_async(image_data):
    width, height = 1920, 1080
    img = pylibheif.HeifImage(width, height, 
                              pylibheif.HeifColorspace.RGB,
                              pylibheif.HeifChroma.InterleavedRGB)
    img.add_plane(pylibheif.HeifChannel.Interleaved, width, height, 8)
    arr = img.get_plane(pylibheif.HeifChannel.Interleaved, True)
    arr[:] = image_data

    async with pylibheif.AsyncHeifContext() as ctx:
        encoder = pylibheif.AsyncHeifEncoder(pylibheif.HeifCompressionFormat.HEVC)
        encoder.set_lossy_quality(85)
        
        # Asynchronously encode (offloaded to thread)
        await encoder.encode_image(ctx, img)
        
        # Asynchronously write to file
        await ctx.write_to_file('output.heic')

asyncio.run(write_async(your_image_data))

API Reference

class pylibheif.HeifContext

Manages the valid lifetime of libheif context. It is the main entry point (root object) for high-level API.

Methods

__init__() Creates a new empty context.

read_from_file(filename: str) -> None Reads a HEIF file from the given filename.

  • filename: Path to the HEIF file.

read_from_memory(data: bytes) -> None Reads a HEIF file from a bytes object.

  • data: Bytes containing the file content.

write_to_file(filename: str) -> None Writes the current context to a file.

  • filename: Destination path.

write_to_bytes() -> bytes Writes the current context to a bytes object.

  • Returns: bytes object containing the encoded file data.

get_primary_image_handle() -> HeifImageHandle Gets the handle for the primary image in the file.

  • Returns: HeifImageHandle for the primary image.

get_image_handle(id: int) -> HeifImageHandle Gets the handle for a specific image ID.

  • id: The ID of the image (see get_list_of_top_level_image_IDs).
  • Returns: HeifImageHandle.

get_list_of_top_level_image_IDs() -> List[int] Gets a list of IDs of all top-level images in the file.

  • Returns: List of integer IDs.

add_exif_metadata(handle: HeifImageHandle, data: bytes) -> None Adds EXIF metadata to the specified image.

  • handle: Image handle from encoding.
  • data: Raw EXIF bytes (with 4-byte offset prefix for TIFF header).

add_xmp_metadata(handle: HeifImageHandle, data: bytes) -> None Adds XMP metadata to the specified image.

  • handle: Image handle from encoding.
  • data: XMP XML as bytes.

add_generic_metadata(handle: HeifImageHandle, data: bytes, item_type: str, content_type: str = "") -> None Adds generic/custom metadata to the specified image.

  • handle: Image handle from encoding.
  • data: Raw metadata bytes.
  • item_type: Metadata item type (e.g. "json", "iptc").
  • content_type: Optional MIME content type (e.g. "application/json").

class pylibheif.HeifImageHandle

Represents a compressed image within the HEIF file.

Properties

  • width (int): The width of the image.
  • height (int): The height of the image.
  • has_alpha (bool): True if the image has an alpha channel.
  • has_content_light_level (bool): True if CLLI metadata is present.
  • has_mastering_display_colour_volume (bool): True if MDCV metadata is present.
  • has_ambient_viewing_environment (bool): True if AMVE metadata is present.
  • content_light_level (Optional[HeifContentLightLevel]): CLLI metadata if present, otherwise None.
  • mastering_display_colour_volume (Optional[HeifMasteringDisplayColourVolume]): MDCV metadata if present, otherwise None.
  • ambient_viewing_environment (Optional[HeifAmbientViewingEnvironment]): AMVE metadata if present, otherwise None.

Methods

decode(colorspace: HeifColorspace = HeifColorspace.RGB, chroma: HeifChroma = HeifChroma.InterleavedRGB) -> HeifImage Decodes the image handle into an uncompressed HeifImage.

  • colorspace: Target colorspace (default: RGB).
  • chroma: Target chroma format (default: InterleavedRGB).
  • Returns: Decoded HeifImage.

get_metadata_block_ids(type_filter: str = "") -> List[str] Gets a list of metadata block IDs attached to this image.

  • type_filter: Optional filter string (e.g. "Exif", "XMP").
  • Returns: List of metadata ID strings.

get_metadata_block_type(id: str) -> str Gets the type string of a specific metadata block.

  • id: Metadata ID.
  • Returns: Type string (e.g. "Exif").

get_metadata_block(id: str) -> bytes Gets the raw data of a metadata block.

  • id: Metadata ID.
  • Returns: bytes object containing the metadata.

class pylibheif.HeifImage

Represents an uncompressed image containing pixel data. Supports zero-copy memory access via nanobind's ndarray integration.

Properties

  • width (int): The width of the image.
  • height (int): The height of the image.
  • has_content_light_level (bool): True if CLLI metadata is present.
  • has_mastering_display_colour_volume (bool): True if MDCV metadata is present.
  • has_ambient_viewing_environment (bool): True if AMVE metadata is present.
  • content_light_level (Optional[HeifContentLightLevel]): Get or set CLLI metadata.
  • mastering_display_colour_volume (Optional[HeifMasteringDisplayColourVolume]): Get or set MDCV metadata.
  • ambient_viewing_environment (Optional[HeifAmbientViewingEnvironment]): Get or set AMVE metadata.

Methods

__init__(width: int, height: int, colorspace: HeifColorspace, chroma: HeifChroma) Creates a new empty image.

  • width: Image width.
  • height: Image height.
  • colorspace: Image colorspace.
  • chroma: Image chroma format.

add_plane(channel: HeifChannel, width: int, height: int, bit_depth: int) -> None Adds a new plane to the image.

  • channel: The channel type (e.g. HeifChannel.Interleaved).
  • width: Width of the plane.
  • height: Height of the plane.
  • bit_depth: Bit depth (e.g. 8).

get_plane(channel: HeifChannel, writeable: bool = False) -> np.ndarray Gets a zero-copy NumPy array mapping to the image plane memory.

  • channel: The channel to retrieve.
  • writeable: Whether the buffer should be writable.
  • Returns: numpy.ndarray mapped to the underlying libheif memory.

class pylibheif.HeifEncoder

Controls the encoding process.

Properties

  • parameters (HeifEncoderParametersProxy): A dictionary-like interface providing access to all configurable encoder parameters. It dynamically routes settings to the correct type-safe setters with validation.

Methods

__init__(format: HeifCompressionFormat) Creates a new encoder for the specified format.

  • format: Compression format (e.g. HeifCompressionFormat.HEVC).

set_lossy_quality(quality: int) -> None Sets the quality for lossy compression.

  • quality: Integer between 0 (lowest) and 100 (highest).

set_lossless(lossless: bool) -> None Enables or disables lossless compression.

set_parameter(name: str, value: str) -> None Sets a low-level encoder parameter as a string.

  • name: Parameter name.
  • value: Parameter value.

get_parameter(name: str) -> str Gets the string representation of a parameter value.

set_integer_parameter(name: str, value: int) -> None get_integer_parameter(name: str) -> int set_boolean_parameter(name: str, value: bool) -> None get_boolean_parameter(name: str) -> bool set_string_parameter(name: str, value: str) -> None get_string_parameter(name: str) -> str Type-safe getters and setters for parameter values.

encode_image(context: HeifContext, image: HeifImage, preset: str = "") -> HeifImageHandle Encodes the given image and appends it to the context.

  • context: The destination HeifContext.
  • image: The source HeifImage to encode.
  • preset: Optional encoder preset (e.g. "ultrafast", "slow"). Default is empty (balanced/default). Note: This maps to the 'preset' parameter in libheif. It works for x265 (check version), but AOM and others may use different parameters (e.g. 'speed') which should be set via set_parameter or parameters instead.
  • Returns: HeifImageHandle for the encoded image. Can be used to add metadata.

Encoder Parameters Introspection

pylibheif supports inspecting and dynamically validating encoder parameters at runtime using encoder.parameters.

class pylibheif.HeifEncoderParameter

Describes a parameter supported by the selected encoder.

  • name (str): Parameter name.
  • type (HeifEncoderParameterType): Data type of the parameter (Integer, Boolean, or String).
  • has_default (bool): Whether the parameter has a default value.
  • default_value (Union[int, bool, str, None]): The default value.
  • valid_integer_range (Optional[Tuple[int, int]]): Min and max allowed integers if bounded.
  • valid_integer_values (Optional[List[int]]): Specific allowed integers.
  • valid_string_values (Optional[List[str]]): Specific allowed string choices.

enum pylibheif.HeifEncoderParameterType

  • Integer
  • Boolean
  • String

HDR Metadata Classes

class pylibheif.HeifContentLightLevel

Holds Content Light Level Information (CLLI) as integers.

  • max_content_light_level (int): Maximum content light level (MaxCLL) in nits.
  • max_pic_average_light_level (int): Maximum picture average light level (MaxFALL) in nits.

class pylibheif.HeifMasteringDisplayColourVolume

Holds Mastering Display Colour Volume (MDCV) metadata. All coordinates are normalized CIE 1931 xy floating-point coordinates.

  • red_primary (Tuple[float, float]): Chromaticity coordinates (x, y) of the red primary.
  • green_primary (Tuple[float, float]): Chromaticity coordinates (x, y) of the green primary.
  • blue_primary (Tuple[float, float]): Chromaticity coordinates (x, y) of the blue primary.
  • white_point (Tuple[float, float]): Chromaticity coordinates (x, y) of the white point.
  • max_luminance (float): Maximum display mastering luminance in nits.
  • min_luminance (float): Minimum display mastering luminance in nits.

class pylibheif.HeifAmbientViewingEnvironment

Holds Ambient Viewing Environment (AMVE) metadata.

  • ambient_illumination (float): Ambient illumination in lux.
  • ambient_light (Tuple[float, float]): Chromaticity coordinates (x, y) of the ambient light.

class pylibheif.AsyncHeifContext

Asynchronous wrapper for HeifContext. Methods are awaited and offloaded to a background thread.

Methods

async read_from_file(filename: str) -> None async read_from_memory(data: bytes) -> None async write_to_file(filename: str) -> None async write_to_bytes() -> bytes get_primary_image_handle() -> AsyncHeifImageHandle get_image_handle(id: int) -> AsyncHeifImageHandle


class pylibheif.AsyncHeifImageHandle

Asynchronous wrapper for HeifImageHandle.

Methods

async decode(colorspace, chroma) -> HeifImage Asynchronously decodes the image.


class pylibheif.AsyncHeifEncoder

Asynchronous wrapper for HeifEncoder.

Properties

  • parameters (HeifEncoderParametersProxy): Synchronous dictionary-like proxy to access and set encoder parameters.

Methods

async encode_image(ctx, image, preset="") -> HeifImageHandle Asynchronously encodes the image.


Enums

pylibheif.HeifColorspace

  • RGB, YCbCr, Monochrome, Undefined

pylibheif.HeifChroma

  • InterleavedRGB: Interleaved R, G, B bytes.
  • InterleavedRGBA: Interleaved R, G, B, A bytes.
  • C420: YUV 4:2:0 planar.
  • C422: YUV 4:2:2 planar.
  • C444: YUV 4:4:4 planar.
  • Monochrome.

pylibheif.HeifChannel

  • Interleaved: For interleaved RGB/RGBA.
  • Y, Cb, Cr: For YUV planar.
  • R, G, B: For RGB planar.
  • Alpha: For Alpha channel.

pylibheif.HeifCompressionFormat

  • HEVC: H.265 (libx265).
  • AV1: AV1 (AOM/RAV1E/SVT).
  • JPEG: JPEG.
  • JPEG2000: JPEG 2000 (OpenJPEG).

Building from Source

# Clone with submodules
git clone --recursive https://github.com/your-username/pylibheif.git
cd pylibheif

# Build
uv pip install -e .

Performance

Benchmarks on 1920x1080 (HD) RGB real-world images (Apple Silicon), comparing python libraries.

Operation Library / Encoder Mean Time
Decoding pillow-heif ~60.5 ms
Decoding pylibheif (HEVC) ~71.3 ms
Encoding pylibheif / Kvazaar ~174.4 ms
Encoding pillow-heif / x265 ~247.3 ms
Encoding pylibheif / x265 (Q80) ~255.7 ms
Encoding pylibheif / AV1 (AOM) ~292.4 ms

Key Findings:

  1. Decoding Parity: pylibheif natively fetching Python 0-copy numpy arrays from underlying native libheif decoders delivers heavily competitive and fast decode speeds within 10ms of specially tuned PIL alternatives.
  2. HEVC Performance: The kvazaar encoder significantly outperforms the default fallback x265 options available in other packages while retaining identical interfaces.
  3. Versatility: pylibheif brings near-realtime AV1 encoding capabilities reliably into Python ecosystem bounds without falling apart gracefully scaling AV1 complexity.
Raw Benchmark Output (Apple M Series)
-----------------------------------------------------------------------------------------------------------------------------------
Name (time in ms)                          Mean            OPS
-----------------------------------------------------------------------------------------------------------------------------------
test_benchmark_decode_hevc_pillow         60.56          16.49  (pillow-heif)
test_benchmark_decode_hevc                71.34          14.01  (pylibheif direct)
test_benchmark_encode_kvazaar            174.47           5.73  (pylibheif, kvazaar, Q80)
test_benchmark_encode_hevc_pillow        247.33           4.04  (pillow-heif, x265, Q80)
test_benchmark_encode_hevc               255.72           3.91  (pylibheif, x265, Q80)
test_benchmark_encode_av1                292.44           3.41  (pylibheif, aom, speed=6)
-----------------------------------------------------------------------------------------------------------------------------------

Run benchmarks yourself:

uv pip install pillow-heif pytest-benchmark
uv run pytest tests/test_benchmark.py --benchmark-only --benchmark-min-rounds=20

License

This project is licensed under the LGPL-3.0 License - see the LICENSE file for details.

Acknowledgments

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylibheif-1.23.0.post1.tar.gz (3.4 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pylibheif-1.23.0.post1-cp314-cp314-win_amd64.whl (6.5 MB view details)

Uploaded CPython 3.14Windows x86-64

pylibheif-1.23.0.post1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibheif-1.23.0.post1-cp314-cp314-macosx_14_0_arm64.whl (5.6 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

pylibheif-1.23.0.post1-cp313-cp313-win_amd64.whl (6.4 MB view details)

Uploaded CPython 3.13Windows x86-64

pylibheif-1.23.0.post1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibheif-1.23.0.post1-cp313-cp313-macosx_14_0_arm64.whl (5.6 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

pylibheif-1.23.0.post1-cp312-cp312-win_amd64.whl (6.4 MB view details)

Uploaded CPython 3.12Windows x86-64

pylibheif-1.23.0.post1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibheif-1.23.0.post1-cp312-cp312-macosx_14_0_arm64.whl (5.6 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

pylibheif-1.23.0.post1-cp311-cp311-win_amd64.whl (6.4 MB view details)

Uploaded CPython 3.11Windows x86-64

pylibheif-1.23.0.post1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibheif-1.23.0.post1-cp311-cp311-macosx_14_0_arm64.whl (5.6 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

File details

Details for the file pylibheif-1.23.0.post1.tar.gz.

File metadata

  • Download URL: pylibheif-1.23.0.post1.tar.gz
  • Upload date:
  • Size: 3.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pylibheif-1.23.0.post1.tar.gz
Algorithm Hash digest
SHA256 b649862751c6101fd2a30d9fa384b3aa449fc0f7ad65c82aa0cb256f5a142812
MD5 02f30f2bd510fb249a39b3e1b7a11773
BLAKE2b-256 27395b6f467c335a06308f9a31928b59cbdfd4eaed548facde80b918bf3b7dcd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1.tar.gz:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 9510bfa9b1c6c23aab17de6706bf9d9199e1a09082514fa8fb002fa49792cd9f
MD5 848416c68a8a78b9607f33b1ce1b90b3
BLAKE2b-256 5959a6e3696058021287926e89ff32e8bfce4ab4fe2569e0a160db95572c54d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp314-cp314-win_amd64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e4cc32a311282ec3b8a63d8b14797cf5fdf29adcebc95051ad5b97a06d5f2de2
MD5 b0ffa114426ef0a76d028e578aa61967
BLAKE2b-256 70505faa0bb7ddd2453979f0456d4ae117a1125aaf6fc6cd16e0b36c9c24ff48

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 f9889bd90453c30ef5b6254787f4a515ecfbcfe1fb084d4cb0b48d211e133d8a
MD5 f6216aaf1995f6722ea62ddb59dce831
BLAKE2b-256 010414ea1374aabc4b3027a75edc93a2bffc979baeab31cfbba6b8ff1f6bc868

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp314-cp314-macosx_14_0_arm64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c0201955f594c49475809fd28b94b0e6397c5cb9fe85900cb330a48625acdae9
MD5 5c73d525fe767c49c8bcd9be3c8176eb
BLAKE2b-256 a0dc7aa85510e51979683fc291c464b96f0f65bbf1e0f03f2bcfb37cfef9ef2b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp313-cp313-win_amd64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e1a1088cc0448b38631902c8b221078ccc92736edaf378991af5b341a88bbb95
MD5 56278eaad8068f549683e6b9de9dd9a7
BLAKE2b-256 2a172d27f5b44272e34c7d462e63797d17fbb7f2693c1d5a5bb257b81cebc482

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 ef200390d3d46f12774fb579dc13419a49a3a2ad3e4ad37083a33afff891d418
MD5 8f3e11e6bfb542f97efe4dc0326872f2
BLAKE2b-256 06298579323dd0b4483fa309ca0cac740fa6824f0438c1dd7dc4fa8bd05bd8b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 603ac669e826d3572c97f34c93a51722094ee810cb2a6e84c34601b7cec2593c
MD5 4f14f5e821ed4c3b6e01c301154b1cfd
BLAKE2b-256 2c2e7505b73de51fef19d747d23fdda9b362ef6a261816bb44aedbcbff79d21a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp312-cp312-win_amd64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 34f409eb753eaca806b9666390b12b8dc56cb67f5e98de11d254d2d4abc375bc
MD5 8de1353fa0ceaf483aadbe73b95827e3
BLAKE2b-256 60933141783d066e5c533a9659a9007bcabd9c1630e8d5327eba86b62e03e1f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 a721b6550fd5d1a4f27859f87b48e780f1d616b9ba6c16f06d4214ecd2330dc6
MD5 2ab15c80cc187647f71f0f8549ab89c3
BLAKE2b-256 84f0233f268e4cbe9eb3f741e7a3ebdf74b107fc2e8caa78954212655b871ac8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 320c14009f17f66c2bd344e5132ac1842179533a0f52c06572ed42c1b880f529
MD5 0c7fe697caa83192cae1581c4323706a
BLAKE2b-256 ce830f75b33a9832318c2fb26c95116df98e86e41f6fa808b87bd9fcb61798e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp311-cp311-win_amd64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3cdd3cb45a9e3036e6c8e21c9d8b8dfdd2b188367fbdf917b41a1be253e67150
MD5 0358ba895cbe19c3055bd805a0243303
BLAKE2b-256 18fa34f08b6a0e36c945a77086517ea8c5e989c9d5fa0f9e228b34166cb3b310

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibheif-1.23.0.post1-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pylibheif-1.23.0.post1-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 482b5df501b6ca44ad370820a11e88a5d6edb286489a17ee0421c5c7e04402fe
MD5 dbfbf47848e87ec70bdb42bab7e44479
BLAKE2b-256 3485f0211d3651cd037711f03dfe86b631831c5c1194e156006cdecb3f7d1d92

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibheif-1.23.0.post1-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: build.yml on twn39/pylibheif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page