2

Short Version: HEIC images need to have even numbered dimensions. In previous versions of ImageMagick installed by Homebrew, libheif 1.7.0 used a kludge to round down image dimensions to even values to allow images with odd numbered dimensions to be converted.

Now libheif 1.8.0 has ditched that kludge and generates images in such cases that macOS seemingly cannot open despite them being valid HEIC files.

While Apple irons out whatever needs to be done to fix this, what can be done in the interim to allow for the clean conversion of such images in a way that allows macOS to open them?


Longer Version: I’ve been using ImageMagick to convert piles of high resolution JPEG images to HEIC format — to save on file space and data transfer times while retaining quality — on and off since around July 2020. I am using macOS Catalina 10.5.6 (19G2021) and ImageMagick has been installed and updated via Homebrew.

This past month something odd happened while converting a small directory filled with images: Seemingly arbitrary images would convert to HEIC, but I could not open them up in the “Preview” app or even Pixelmator in macOS. No preview icon was generated either. Making things weirder is that if I took that HEIC image and then converted it back to a JPEG, the conversion worked. So the HEIC was valid in some way, but not in a way that macOS’s native API could handle.

According to this comment on an issue report on the ImageMagick repo it turns out that libheif — the library that handles HEIC stuff in ImageMagick — was recently upgraded to 1.8.0 and that new version handles the conversion of images with odd numbered dimensions differently than versions of libheif 1.7.0 and earlier. In the case of images with odd dimensions it creates HEIC images that uses a clap (Clean Aperture) crop transform and macOS apparently has no idea how to deal with that. And checking my pile of unopenable images, they all have at least one dimension (width or height) in an odd number value.

So while this is clearly an issue with macOS and how it natively handles HEIC files, what can I do now to get back to bulk converting images that can be viewed in macOS? Downgrading to libheif 1.7.0 seems messy and is a bit regressive.

If you want to test this for yourself, try this command using this test image on Wikimedia that has a 3111 width by 3333 height; just rename the image test.jpeg for this:

convert test.jpg test.heic

Or try to do the same using the libheif utility heif-enc like this:

heif-enc test.jpg -o test.heic

In both cases, the macOS “Preview” app — and other applications — can’t open the generated test.heic file. But it clearly can be converted back to a JPEG like this from the command line using ImageMagick:

convert test.heic test.jpg

1 Answer 1

2

Get ImageMagick to “round up” odd dimensions to the next even value during the conversion process.

Can’t rely on Apple to update/patch macOS’s API to handle these clap images any time soon, so my solution right now is to use ImageMagick itself to “round up” odd dimensions to the next even pixel dimension and then have that image converted to HEIC.

The solution comes from this StackOverflow answer that uses ImageMagick’s -extent option with a nested call to check the image size with -format like so:

convert source.jpg -background white -extent  $(convert source.jpg -format '%[fx:2*int((w+1)/2)]x%[fx:2*int((h+1)/2)]!' info:) destination.heic

The nested convert call would output something like this based on this test image on Wikimedia that has a 3111 width by 3333 height:

3112x3334!

Yes, it’s adding one pixel to width and height but for many purposes this is negligible. It’s a workaround that works, especially for high resolution images.

And here is the full Bash script I use to handle these bulk conversions nowadays:

find -E 'Desktop/Pics' -type f -iregex '.*\.(JPG|JPEG|PNG|TIF|TIFF)$' |\
  while read FULL_IMAGE_PATH
  do
    PATH_SANS_EXTENSION="${FULL_IMAGE_PATH%.*}"
    convert "${FULL_IMAGE_PATH}" -background white -extent  $(convert "${FULL_IMAGE_PATH}" -format '%[fx:2*int((w+1)/2)]x%[fx:2*int((h+1)/2)]!' info:) "${PATH_SANS_EXTENSION}".heic
    exiftool -overwrite_original_in_place -tagsFromFile "${FULL_IMAGE_PATH}" "${PATH_SANS_EXTENSION}".heic
  done

libheif 1.9.0 now has a new built-in option to crop down odd dimensions by one pixel to make image dimensions an even number.

According to this comment on an issue thread for libheif, version 1.9.0 of libheif now has a -E/--even-size option that addresses this issue.

After updating my local Homebrew install of libheif to version I was able to test this. When I ran this basic command without the -E option:

heif-enc source.jpeg -o destination.heic

I see this helpful warning:

Warning: HEIF images with odd width or height cannot be displayed by many programs on macOS (tested up to Catalina 10.15.6). Until macOS is fixed or we have a workaround, it is advised to use option -E to make the image size an even number.

And the resulting image is just like before; valid but not openable in macOS.

But if I run the same exact command with the -E option like this:

heif-enc -E source.jpeg -o destination.heic

The destination.heic is valid and openable in macOS!

Knowing that I can adjust my own Bash script — that uses ImageMagick — to use heif-inc directly like this:

find -E 'Desktop/Pics' -type f -iregex '.*\.(JPG|JPEG|PNG|TIF|TIFF)$' |\
  while read FULL_IMAGE_PATH
  do
    PATH_SANS_EXTENSION="${FULL_IMAGE_PATH%.*}"
    heif-enc -E "${FULL_IMAGE_PATH}" -o "${PATH_SANS_EXTENSION}".heic
    exiftool -overwrite_original_in_place -tagsFromFile "${FULL_IMAGE_PATH}" "${PATH_SANS_EXTENSION}".heic
  done

Just note the -E option crops down the image by one pixel to make the dimensions even, while the ImageMagick command that uses that -extent/-format combo adds an extra pixel to make the dimensions even. Might not mean much to some, but just something to keep in mind when choosing which method to use.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .