Python bindings for libheif - HEIC/AVIF/JPEG2000 image codec
Project description
pylibheif
Python bindings for libheif using pybind11.
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 EXIF and XMP metadata from images
- RAII Resource Management: Automatic resource cleanup with context managers
Supported Formats
| Format | Decoding | Encoding | Codec |
|---|---|---|---|
| HEIC (HEVC/H.265) | ✅ | ✅ | libde265 / x265 |
| AVIF (AV1) | ✅ | ✅ | DAV1D + AOM |
| JPEG2000 | ✅ | ✅ | OpenJPEG |
Requirements
- Python >= 3.12
- NumPy >= 1.26.0
- CMake >= 3.15
- C++17 compatible compiler
System Dependencies
# macOS
brew install openjpeg
# Ubuntu/Debian
sudo apt install libopenjp2-7-dev
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)
plane = img.get_plane(pylibheif.HeifChannel.Interleaved, False)
arr = np.asarray(plane) # 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)
plane = img.get_plane(pylibheif.HeifChannel.Interleaved, False)
arr = np.asarray(plane)
# Resources are automatically freed when objects go out of scope
Writing HEIC/AVIF Images
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
plane = img.get_plane(pylibheif.HeifChannel.Interleaved, True)
arr = np.asarray(plane)
arr[:] = your_image_data # your RGB data
# Encode and save
ctx = pylibheif.HeifContext()
# For HEIC (HEVC)
encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.HEVC)
# For AVIF (AV1)
# encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.AV1)
# For JPEG2000
# encoder = pylibheif.HeifEncoder(pylibheif.HeifCompressionFormat.JPEG2000)
encoder.set_lossy_quality(85)
encoder.encode_image(ctx, img)
ctx.write_to_file('output.heic')
Converting HEIC to JPEG
import pylibheif
import numpy as np
from PIL import Image
# Decode HEIC
ctx = pylibheif.HeifContext()
ctx.read_from_file('input.heic')
handle = ctx.get_primary_image_handle()
img = handle.decode(pylibheif.HeifColorspace.RGB,
pylibheif.HeifChroma.InterleavedRGB)
# Get NumPy array
plane = img.get_plane(pylibheif.HeifChannel.Interleaved, False)
arr = np.asarray(plane)
# Save as JPEG using PIL
pil_img = Image.fromarray(arr)
pil_img.save('output.jpg', 'JPEG', quality=85)
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)}')
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:
bytesobject containing the encoded file data.
get_primary_image_handle() -> HeifImageHandle
Gets the handle for the primary image in the file.
- Returns:
HeifImageHandlefor the primary image.
get_image_handle(id: int) -> HeifImageHandle
Gets the handle for a specific image ID.
id: The ID of the image (seeget_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.
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.
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:
bytesobject containing the metadata.
class pylibheif.HeifImage
Represents an uncompressed image containing pixel data. Supports the Python Buffer Protocol for zero-copy access with NumPy.
Properties
width(int): The width of the image.height(int): The height of the image.
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) -> HeifPlane
Gets a plane object that supports the buffer protocol.
channel: The channel to retrieve.writeable: Whether the buffer should be writable.- Returns:
HeifPlaneobject (wrappable withnp.asarray()).
class pylibheif.HeifEncoder
Controls the encoding process.
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_parameter(name: str, value: str) -> None
Sets a low-level encoder parameter.
name: Parameter name (e.g. "speed" for AV1).value: Parameter value.
encode_image(context: HeifContext, image: HeifImage) -> None
Encodes the given image and appends it to the context.
context: The destinationHeifContext.image: The sourceHeifImageto encode.
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 RGB image (Apple Silicon):
| Operation | pylibheif | pillow-heif | Note |
|---|---|---|---|
| HEVC Decode | 25 ms | 25 ms | ~39 FPS |
| HEVC Encode | 279 ms | 272 ms | Quality 80 |
| AV1 Encode | 91 ms | - | Speed 50 |
pylibheif offers performance comparable to pillow-heif (both wrapper libheif), but exposes a lower-level C++ API for fine-grained control.
Run benchmarks yourself:
uv pip install pillow-heif pytest-benchmark
uv run pytest tests/test_benchmark.py --benchmark-only
License
This project is licensed under the LGPL-3.0 License - see the LICENSE file for details.
Acknowledgments
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pylibheif-1.21.2.post1.tar.gz.
File metadata
- Download URL: pylibheif-1.21.2.post1.tar.gz
- Upload date:
- Size: 2.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f78d75f311b5061f1bffc7304df23cdfec55ddb2a87fe83d113018920c92e0d3
|
|
| MD5 |
71f28ac88023837088ae4a187a6fc2ba
|
|
| BLAKE2b-256 |
5201ad7477c285d072dfc6638d95e67b8b99e55e65f161b3ad169053b63d0ec2
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1.tar.gz:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1.tar.gz -
Subject digest:
f78d75f311b5061f1bffc7304df23cdfec55ddb2a87fe83d113018920c92e0d3 - Sigstore transparency entry: 903206452
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 5.9 MB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebd21b6499be85d29c2e2e8f4b43481604693313ab15ba420981984f08a56003
|
|
| MD5 |
acc44ba83f9261101928c697cff5e704
|
|
| BLAKE2b-256 |
ec976babd2b6369196d4664cc5cec6cb0542ba6a2d1eba99844d36615fb340fb
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp313-cp313-manylinux_2_28_x86_64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp313-cp313-manylinux_2_28_x86_64.whl -
Subject digest:
ebd21b6499be85d29c2e2e8f4b43481604693313ab15ba420981984f08a56003 - Sigstore transparency entry: 903206703
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp313-cp313-macosx_14_0_arm64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp313-cp313-macosx_14_0_arm64.whl
- Upload date:
- Size: 5.8 MB
- Tags: CPython 3.13, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67eec504edb54aa15b25c093d44b29975bfd2bb9b5602ecdedfdf667e167b889
|
|
| MD5 |
85a5fce5e13c6448b996bd786f0ecbea
|
|
| BLAKE2b-256 |
badbfdce41e370d134fb06c837e2d5d0a50a2f28b5e4072878c5e0251ac51231
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp313-cp313-macosx_14_0_arm64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp313-cp313-macosx_14_0_arm64.whl -
Subject digest:
67eec504edb54aa15b25c093d44b29975bfd2bb9b5602ecdedfdf667e167b889 - Sigstore transparency entry: 903206847
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 5.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f735a31a8291bf5cbbabe978fd996a312506ee558ac973ffb85699ffa234c1d4
|
|
| MD5 |
03832bf867ac9f43d727be20624f2205
|
|
| BLAKE2b-256 |
3023b803a54e335be6cc76005340419c71016c6217b38bdc3675395a8d4f2415
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp312-cp312-manylinux_2_28_x86_64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp312-cp312-manylinux_2_28_x86_64.whl -
Subject digest:
f735a31a8291bf5cbbabe978fd996a312506ee558ac973ffb85699ffa234c1d4 - Sigstore transparency entry: 903206646
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp312-cp312-macosx_14_0_arm64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp312-cp312-macosx_14_0_arm64.whl
- Upload date:
- Size: 5.8 MB
- Tags: CPython 3.12, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4eda5a2e7e33447a1f6bfc7d2f3fa5f9f95d7495a92537807a837f85d940cf26
|
|
| MD5 |
4a27d1a854d17e232561784f82d90971
|
|
| BLAKE2b-256 |
e1e44a223097686ae3690783cfd9558f5a2138d349e744e07f9cd2d234b80ceb
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp312-cp312-macosx_14_0_arm64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp312-cp312-macosx_14_0_arm64.whl -
Subject digest:
4eda5a2e7e33447a1f6bfc7d2f3fa5f9f95d7495a92537807a837f85d940cf26 - Sigstore transparency entry: 903206587
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 5.9 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cf1fbd2608160d2b68015fdb1f06fac1c8c19a18c8e4125d694329e4590cdf1
|
|
| MD5 |
c5a6175ebdbddf7de06784a70cff83c4
|
|
| BLAKE2b-256 |
f96fefb864cfecf3aab40efc6433927375a0f14bb2d513ec67b49f9bf5c89db5
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp311-cp311-manylinux_2_28_x86_64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp311-cp311-manylinux_2_28_x86_64.whl -
Subject digest:
9cf1fbd2608160d2b68015fdb1f06fac1c8c19a18c8e4125d694329e4590cdf1 - Sigstore transparency entry: 903206766
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylibheif-1.21.2.post1-cp311-cp311-macosx_14_0_arm64.whl.
File metadata
- Download URL: pylibheif-1.21.2.post1-cp311-cp311-macosx_14_0_arm64.whl
- Upload date:
- Size: 5.8 MB
- Tags: CPython 3.11, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ee5ccfa7ad7f0d05a78eba94dca034f5b46cc70697f016ebaba27a400c0473b
|
|
| MD5 |
f1ede3559b48c7afa0401f37fc7960c7
|
|
| BLAKE2b-256 |
5a36f08cb30ef7dcb3da4b3cbdfb56df27a2a827816999df9e7f93cfc2a57be4
|
Provenance
The following attestation bundles were made for pylibheif-1.21.2.post1-cp311-cp311-macosx_14_0_arm64.whl:
Publisher:
build.yml on twn39/pylibheif
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylibheif-1.21.2.post1-cp311-cp311-macosx_14_0_arm64.whl -
Subject digest:
8ee5ccfa7ad7f0d05a78eba94dca034f5b46cc70697f016ebaba27a400c0473b - Sigstore transparency entry: 903206524
- Sigstore integration time:
-
Permalink:
twn39/pylibheif@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Branch / Tag:
refs/tags/v1.21.2.post1 - Owner: https://github.com/twn39
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@46ea10ed265a85a8e2a7c0920ed9d504a020b320 -
Trigger Event:
push
-
Statement type: