Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

heif-image-plugin

Linux macOS Python coverage Py Versions license

A HEIF/HEIC and AVIF plugin for Pillow based on libheif.

Installation

You can install heif-image-plugin from PyPI:

pip install heif-image-plugin

Bundled libheif and codecs

pip install 'heif-image-plugin[libheif]'

The [libheif] extra installs the libheif-binary package, which provides libheif and codecs. The plugin uses this package when installed; otherwise, it requires system libheif.

Ubuntu system libheif

Ubuntu 24.04:

apt-get install --no-install-recommends \
    libheif1 \
    libheif-plugin-libde265 \
    libheif-plugin-x265 \
    libheif-plugin-aomenc

Minimal supported libheif version is 1.17.x.

macOS with Homebrew

The macOS wheel expects @rpath/libheif.1.dylib, while Homebrew's libheif uses an absolute install name. Build the extension against Homebrew's library so it records the correct path.

With a C compiler and Python development headers available, run the following from the repository root in a Python environment without libheif-binary:

brew install libheif
pip install 'setuptools>=77.0.3' 'cffi>=1.15.1'
pip install --no-build-isolation .

--no-build-isolation prevents pip from installing libheif-binary as a build dependency. On macOS, the build automatically detects Homebrew's libheif when brew is on PATH and libheif-binary is absent. If Homebrew's libheif is not installed, the build uses the standard system library search.

How to use

Just import once before opening an image.

from PIL import Image, ImageOps
import HeifImagePlugin

image = Image.open('test.heic')
ImageOps.exif_transpose(image, in_place=True)
# requires libheif with a HEVC or AV1 encoder
image.save('test.avif')

Decoding errors are exposed as HeifImagePlugin.HeifError, with code, subcode and message fields.

The plugin follows Pillow's Image.MAX_IMAGE_PIXELS error threshold. Set it to None to disable pixel and decoding memory limits; 0 rejects nonempty images.

HeifImagePlugin.MAX_METADATA_BYTES defaults to 50 MiB and limits opening memory and individual ICC profiles, not total process memory. Set it before opening an image; None disables it, while 0 is clamped to one byte. These limits require libheif 1.19+. Decoded pixels can exceed this opening budget.

For direct use of _heif_image_plugin.reader.open(), max_pixels sets the pixel cap and a decoding memory budget of four bytes per pixel; max_metadata_bytes sets the opening memory budget and ICC-profile cap. Each argument defaults to None (preserve native defaults); 0 disables its limits independently.

Downsampling defaults to 'best', which selects 'sharp-yuv' for RGB/RGBA images with 4:2:0 subsampling when supported, and 'average' otherwise.

Encoder-specific parameters can be passed when saving:

image.save(
    'test.avif',
    quality=90,
    subsampling='420',
    downsampling='average',
    encoder='aom',
    concurrency=4,
    encoder_params={'speed': 6},
)

To encode AVIF with SVT-AV1, use encoder='svt'. SVT supports only 4:2:0 subsampling; omit subsampling or set it to '420':

image.save('test.avif', encoder='svt', subsampling='420')

How to contribute

Contributions are welcome:

  1. Clone the repository: git clone https://github.com/uploadcare/heif-image-plugin.git.
  2. Build the development image: make docker_build.
  3. Start a development shell: make docker_shell.
  4. Make your changes and add tests.
  5. Run make lint and make test inside the container.
  6. Commit your changes on a new branch and open a pull request against uploadcare/heif-image-plugin.

Building from source

Building from source requires a C compiler and Python development headers. On Linux and macOS, a normal pip install . automatically installs libheif headers and libraries in an isolated build environment. Install runtime libheif separately, using the [libheif] extra or system packages described above.

To build against system libheif without libheif-binary, install libheif development headers and its library, plus setuptools and CFFI, then run:

pip install --no-build-isolation .

Changelog

0.9.0

  • Reading and saving now use libheif directly. The pyheif dependency is removed. The heif-enc executable and HEIF_ENC_BIN setting are no longer used. Saving no longer uses temporary files or subprocesses.
  • Added the [libheif] installation extra, which installs libheif-binary. Without this extra, system libheif 1.17 or later is required.
  • Wheels for CPython 3.9+ are provided for Linux (glibc 2.28+ and musl 1.2+, on x86_64 and ARM64) and macOS 11+ (universal2). Other platforms require a source build, as does using libheif from Homebrew.
  • Decoding errors now use HeifImagePlugin.HeifError instead of pyheif.error.HeifError.
  • Applied Pillow's pixel error threshold to native opening and decoding limits. Added MAX_METADATA_BYTES with a default opening memory budget of 50 MiB.
  • Changed default chroma downsampling from average to best: uses sharp-yuv when possible, and average otherwise.
  • Enabled bilinear chroma upsampling during decoding for 4:2:2 with libheif 1.19.0+ and for 4:2:0 with libheif 1.23.6+.
  • Added saving of palette images (P and PA modes), including transparency.
  • Grayscale images with alpha (LA mode) are now encoded directly, without converting to RGBA on older libheif versions.
  • Saving now preserves the displayed EXIF orientation across supported libheif versions.

0.8.1

  • Added SVT-AV1 support for AVIF encoding with encoder='svt' (4:2:0 subsampling only)

0.8.0

  • Minimal supported Python version is 3.9
  • Minimal supported libheif version is 1.17.x
  • Added encoder_params parameter for passing custom encoder parameters when saving
  • Changed the default chroma downsampling algorithm from nn to average
  • Default chroma subsampling is now explicitly set to 4:2:0

0.7.0

  • Depends on pyheif>=0.8.0; dropped support for older versions

0.6.2

  • Fix for buggy LA mode in libheif 1.17.0 - 1.18.2
  • Fixed unsupported color conversion for some images

0.6.1

  • Added compatibility with Pillow 10.1+

0.6.0

  • Minimal supported pyheif is 0.7.1
  • Added downsampling parameter for saving. Works only with subsampling == 2.
  • Transformations support updated to the latest libheif and pyheif

0.5.1

  • Fixed HEIF saving in '1' mode

0.5.0

  • Added HEIF saving support if heif-enc is installed (part of libheif)
  • Fixed HeifImageFile.verify() call
  • Extensions .heic, .avif, .heif, .hif are handled by the plugin

0.4.0

  • Bypass some decoding errors when ImageFile.LOAD_TRUNCATED_IMAGES is True.

0.3.2

  • Depends on latest pyheif.

0.3.1

! This version requires pyheif with pyheif.open API. As of 2021.11.25 this API isn't released and is in pyheif's master. See install-pyheif-master-pillow-latest target in the Makefile to install it.

  • Fixed potential vulnerability with arbitrary data in exif metadata.

0.3.0

! This version requires pyheif with pyheif.open API. As of 2021.11.25 this API isn't released and is in pyheif's master. See install-pyheif-master-pillow-latest target in the Makefile to install it.

  • pyheif.open API is used for lazy images loading.
  • Fixed an error when the plugin tries to load any ISOBMFF files.
  • AVIF files should work before, but now this is official.
  • Patched versions of pyheif and libheif with exposed transformations are supported. In this case opened image isn't transformed on loading and orientation is stored in EXIF Orientation tag like for all other image formats. This is faster and consumes less memory.

0.2.0

  • No need to register, works after import.
  • Fill info['icc_profile'] on loading.
  • Close and release file pointer after loading.
  • Decoding without custom HeifDecoder(ImageFile.PyDecoder).

Acknowledgments

This project started with Christian Bianciotto’s pyheif-pillow-opener.

Metadata

Release files for heif-image-plugin 0.9.0b3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for heif-image-plugin 0.9.0b3
File Size Uploaded Provenance
heif_image_plugin-0.9.0b3.tar.gz 40.5 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for heif-image-plugin 0.9.0b3
File
heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_x86_64.whl CPython 3.9 abi3 Linux glibc 2.28+ x86-64 Details
heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.28+ ARM64 Details
heif_image_plugin-0.9.0b3-cp39-abi3-macosx_11_0_universal2.whl CPython 3.9 abi3 macOS 11.0+ universal2 (ARM64, x86-64) Details

Total release size: 406.4 kB

Release files / heif_image_plugin-0.9.0b3.tar.gz

Download URL heif_image_plugin-0.9.0b3.tar.gz
Size 40.5 kB
Tags Source
SHA-256 checksum
How to use checksums
820efc1f3497993bc764ffa8de4edd85ae6c792431e05cc844f871e3341d0bac
BLAKE2b-256 checksum
How to use checksums
8dbd34fbca64dbdc627854e5e89543e99af077ac0439b34f573031a16b2bfc40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_x86_64.whl
Size 122.6 kB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
6218699fe63220e7be2fcfc4e83a6b0100f6d730cbec8da121ad7b9e31989991
BLAKE2b-256 checksum
How to use checksums
1857201d1be80f1e57dade3d285460ed2734503239f556b773d8f8ea7f62aae0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL heif_image_plugin-0.9.0b3-cp39-abi3-musllinux_1_2_aarch64.whl
Size 109.2 kB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
55aa3850c3d1d7c42477aceab89e8751eae8fdd990870ffb297bb60f7d24d991
BLAKE2b-256 checksum
How to use checksums
6d21c9b1e977db7c80602919c03be8bd5be5292fae4e428d2a8e457bb2a9e80d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_x86_64.whl

Download URL heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_x86_64.whl
Size 40.8 kB
Tags CPython 3.9 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
b89d22001b02de3274d67dd0bbb9708b9582ceae4d169f4bb69766cfe5ec41e8
BLAKE2b-256 checksum
How to use checksums
96e4fb5595810f631c1f7c902d884a829bd58c62f197ec49c6166c97733c0d5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_aarch64.whl

Download URL heif_image_plugin-0.9.0b3-cp39-abi3-manylinux_2_28_aarch64.whl
Size 40.2 kB
Tags CPython 3.9 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
49db066632c83300430ed8f8ae69eaffac625d5fbaa1fd4adef97c1508fae669
BLAKE2b-256 checksum
How to use checksums
0c6905fcd2195d6944beef9f712a05968754d4fcc8165da6e2ed3c35ad561481
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / heif_image_plugin-0.9.0b3-cp39-abi3-macosx_11_0_universal2.whl

Download URL heif_image_plugin-0.9.0b3-cp39-abi3-macosx_11_0_universal2.whl
Size 53.1 kB
Tags CPython 3.9 abi3 macOS 11.0+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
dc4ea9c6f22dbf1fac1cfbaf84c788b048d1e0c482cdc75a9a721d0dd869b750
BLAKE2b-256 checksum
How to use checksums
667e74f456344a298fc9537fc6e9ae98678a6224a9331d257966870242565f9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for heif-image-plugin 0.9.0b3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page