Converting HEIC to PNG

Summary: This post discusses image file formats and describes how to write a Python program to convert from HEIC files to PNG files.

  1. My Problem
  2. Image File Formats
    1. HEIC
    2. PNG
  3. Converting from HEIC to PNG
    1. Option 1: Converting “manually”
    2. Option 2: Writing a Python Program
  4. Pillow-HEIF
  5. My Python Program
  6. References
  7. Footnotes

My Problem

I was making a slide show using LibreOffice1 that contained hundreds of photos. I had discovered a new (to me) functionality2 that enables one to import an entire directory of photos and puts one photo on each slide. This seemed to be working great until I realized that a lot of my newer pictures were missing. It turned out that the reason they were missing is because LibreOffice3 did not recognize HEIC files. In fact, even manually, I could not import pictures stored as HEIC files.

Image File Formats

Images can be stored in many different file formats. These include many familiar ones such as .jpg, .gif, .bmp, .png, .svg, etc. Each of these have their pros and cons. Fortunately, they can usually be converted from one format to another, although often some information is lost in the process.

HEIC

HEIC files contain images encoded in HEVC format. HEVC, in turn, is the default image format used with HEIF. HEIF, which stands for High Efficiency Image File Format, is a container for storing one or more images as well as metadata.

According to Wikipedia, HEIF files can store images, instructions on cropping and rotation, image sequences, depth map and alpha plane information, and metadata.

HEIC is the standard format for images taken with iPhones. It allows for the “live” photos that the phone takes. It also allows reversal of edits to the images.

PNG

PNG, which stands for Portable Network Graphics, is an image format standard that is widely used on the internet because it is not patented and therefore widely available. In addition to being free and widely available, it has the advantages of being lossless and holding true color information.

Unlike HEIC, it stores only one image.

Converting from HEIC to PNG

Option 1: Converting “manually”

It was easy enough to open a file and then save it as a different image type using the built-in Photo app that comes with Windows. However, I soon learned there were too many files to convert this way.

Option 2: Writing a Python Program

Although I didn’t know how to do it, given the number of files I needed to convert, it seemed like a simple Python program would be a better solution. It turns out it was quicker to figure out how to write the program than to convert the files one at a time.

Pillow-HEIF

A quick Google search of “python heic to jpg” lead me to a discussion on Stack Overflow about a snippet of code that will convert HEIC to PNG. Even though this was not what I asked for, .png is a perfectly acceptable format for my need since it is old enough and common enough that LibreOffice would recognize it.

This discussion introduced me to a new package called ‘pillow_heif’, which I installed using the following:

python3 -m pip install pillow-heif

According to PyPi, pillow-heif has the following features:

  • Decoding of 8, 10, 12 bit HEIC and AVIF4 files.
  • Encoding of 8, 10, 12 bit HEIC and AVIF files.
  • EXIF, XMP, IPTC5 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.

PyPi has several examples of how to use the package.

My Python Program

The program is given the directory containing all of the images. It finds all the files in the directory and picks out the HEIC files. It then reads each HEIC file and saves it to PNG using the same filename (with a different extension) into a new folder.

Here is my code:

from PIL import Image
import pillow_heif
import os

root = r'c:\path\'
for path, subdirs, files in os.walk(root):
    for name in files:
        if subdirs != []:
            if name[-4:] == 'HEIC':
                filename = os.path.join(path,name)
                print('Converting ',filename)

                heif_file = pillow_heif.read_heif(filename)
                image = Image.frombytes(
                    heif_file.mode,
                    heif_file.size,
                    heif_file.data,
                    "raw",
                )

                newfile = f'{root}\\Converted\\'{name[:-4]}png'
                image.save(newfile, format("png"))

                print(f'New File: {newfile}\n\n')

References

Footnotes

  1. LIbreOffice is an open source (read: free) clone of Microsoft Office, including word processor, spreadsheet, and presentation software. ↩︎
  2. This functionality is Insert > Media > Photo Album. ↩︎
  3. At least my version of it ↩︎
  4. According to Wikipedia, “AV1 Image File Format (AVIF) is an open, royalty-free image file format specification for storing images or image sequences compressed with AV1 in the HEIF container format. It competes with HEIC, which uses the same container format… but HEVC for compression. ” ↩︎
  5. These are metadata formats. ↩︎

Comments

Leave a comment