Pillow-HEIF
Pillow-HEIF (pi-heif) provides a robust Python interface for the libheif library, enabling reading and writing of HEIF/HEIC image files. It integrates seamlessly with the popular Pillow imaging library, extending its capabilities to support the HEIF format. The library is actively maintained, with version 1.3.0 being the latest, and releases are frequent.
Warnings
- breaking Python 3.9 support was dropped in `v1.2.0`, and Python 3.8 support was dropped in `v0.20.0`. Attempting to install or use these versions on older Python interpreters will fail or lead to errors.
- breaking AVIF format support was deprecated in `v0.22.0` and fully removed in `v1.0.0` due to Pillow gaining native AVIF capabilities. Attempting to open/save AVIF files via `pi-heif` will no longer work.
- gotcha From `v1.2.0`, the `PREFERRED_DECODER` option must always specify a valid and available decoder ID. If not, an exception will be raised, whereas previously it might have silently failed or ignored an invalid setting.
- gotcha A critical integer overflow vulnerability (CVE-2026-28231, GHSA-5gjj-6r7v-ph3x) affecting buffer validation was fixed in `v1.3.0`. This could lead to heap out-of-bounds reads during encoding, potentially allowing arbitrary code execution.
- gotcha On macOS, versions prior to `v1.2.1` could experience crashes when `cv2` (OpenCV Python bindings) and `pillow_heif` were both installed, due to conflicts in bundled `libx265` libraries. This was particularly problematic for users utilizing both image processing libraries.
- gotcha The `pillow_heif.options.DISABLE_SECURITY_LIMITS` boolean was introduced in `v0.22.0` to bypass `libheif`'s internal security limits on image sizes, which might be necessary for very large files. Disabling this can lead to high memory usage.
Install
-
pip install pi-heif
Imports
- register_heif_opener
from pillow_heif import register_heif_opener
- HeifImage
from pillow_heif import HeifImage
Quickstart
import os
from PIL import Image
from pillow_heif import register_heif_opener
# Register HEIF/HEIC support with Pillow
register_heif_opener()
dummy_heic_path = "dummy.heic"
output_jpeg_path = "output.jpg"
try:
# Create a dummy image using Pillow
img = Image.new("RGB", (200, 150), color='blue')
print(f"Created a dummy Pillow image of size {img.size}")
# Save the dummy image as HEIF/HEIC using the registered opener
# Note: HEIF encoding might require libheif to be compiled with specific encoders
# If save fails, ensure libheif has an encoder available.
img.save(dummy_heic_path, format="HEIF", quality=80)
print(f"Saved dummy image to {dummy_heic_path} as HEIF.")
# Open the HEIF/HEIC file using Pillow's Image.open()
with Image.open(dummy_heic_path) as heic_img:
print(f"Successfully opened HEIC image: Format={heic_img.format}, Mode={heic_img.mode}, Size={heic_img.size}")
# Save it as JPEG
heic_img.save(output_jpeg_path)
print(f"Saved HEIC image to {output_jpeg_path} as JPEG.")
except Exception as e:
print(f"An error occurred during quickstart: {e}")
print("This might be due to missing underlying libheif encoders/decoders, or unsupported system configuration.")
finally:
# Clean up created files
if os.path.exists(dummy_heic_path):
os.remove(dummy_heic_path)
print(f"Cleaned up {dummy_heic_path}")
if os.path.exists(output_jpeg_path):
os.remove(output_jpeg_path)
print(f"Cleaned up {output_jpeg_path}")