pillow_heif

Python library for working with HEIF images and plugin for Pillow.

BSD-3-CLAUSE License

Downloads
1M
Stars
207
Committers
10

pillow-heif

Python bindings to libheif for working with HEIF images and plugin for Pillow.

Features:

  • Decoding of 8, 10, 12 bit HEIC and AVIF files.
  • Encoding of 8, 10, 12 bit HEIC and AVIF files.
  • EXIF, XMP, IPTC read & write support.
  • Support of multiple images in one file and a PrimaryImage attribute.
  • Adding & removing thumbnails.
  • Reading of Depth Images.
  • Adding HEIF support to Pillow in one line of code as a plugin.

Note: Here is a light version pi-heif of this project without encoding capabilities.

Install

python3 -m pip install -U pip
python3 -m pip install pillow-heif

Example of use as a Pillow plugin

from PIL import Image
from pillow_heif import register_heif_opener

register_heif_opener()

im = Image.open("image.heic")  # do whatever need with a Pillow image
im = im.rotate(13)
im.save(f"rotated_image.heic", quality=90)

16 bit PNG to 10 bit HEIF using OpenCV

import cv2
import pillow_heif

cv_img = cv2.imread("16bit_with_alpha.png", cv2.IMREAD_UNCHANGED)
heif_file = pillow_heif.from_bytes(
    mode="BGRA;16",
    size=(cv_img.shape[1], cv_img.shape[0]),
    data=bytes(cv_img)
)
heif_file.save("RGBA_10bit.heic", quality=-1)

8/10/12 bit HEIF to 8/16 bit PNG using OpenCV

import numpy as np
import cv2
import pillow_heif

heif_file = pillow_heif.open_heif("image.heic", convert_hdr_to_8bit=False, bgr_mode=True)
np_array = np.asarray(heif_file)
cv2.imwrite("image.png", np_array)

Accessing decoded image data

import pillow_heif

if pillow_heif.is_supported("image.heic"):
    heif_file = pillow_heif.open_heif("image.heic", convert_hdr_to_8bit=False)
    print("image size:", heif_file.size)
    print("image mode:", heif_file.mode)
    print("image data length:", len(heif_file.data))
    print("image data stride:", heif_file.stride)

Get decoded image data as a Numpy array

import numpy as np
import pillow_heif

if pillow_heif.is_supported("input.heic"):
    heif_file = pillow_heif.open_heif("input.heic")
    np_array = np.asarray(heif_file)

AVIF support

Working with the AVIF files as the same as with the HEIC files. Just use a separate function to register plugin:

import pillow_heif

pillow_heif.register_avif_opener()

Accessing Depth Images

from PIL import Image
from pillow_heif import register_heif_opener
import numpy as np

register_heif_opener()

im = Image.open("../tests/images/heif_other/pug.heic")
if im.info["depth_images"]:
    depth_im = im.info["depth_images"][0]  # Access the first depth image (usually there will be only one).
    # Depth images are instances of `class HeifDepthImage(BaseImage)`,
    # so work with them as you would with any usual image in pillow_heif.
    # Depending on what you need the depth image for, you can convert it to a NumPy array or convert it to a Pillow image.
    pil_im = depth_im.to_pillow()
    np_im = np.asarray(depth_im)
    print(pil_im)
    print(pil_im.info["metadata"])

More Information

Wheels

Wheels table macOSIntel macOSSilicon Windows musllinux* manylinux*
CPython 3.9
CPython 3.10
CPython 3.11
CPython 3.12
CPython 3.13
PyPy 3.9 v7.3 N/A
PyPy 3.10 v7.3 N/A

* x86_64, aarch64 wheels.