HEIC Uploads: when the iPhone takes over your forums
For the past few months, a quiet problem had been eating away at my Invision Community forums: photos that no longer displayed. A member uploads a picture, everything seems to go fine, and then at publication… an unusable download link shows up where the image should be. On a forum built around sharing photos, that is a defect you run into every single day.
The culprit has a name: HEIC.
The format nobody displays
Since the iPhone 7 and iOS 11, Apple has shot in HEIC by default, a HEIF container with HEVC compression. Technically, the format is excellent: at equal quality, it weighs half as much as a JPEG. But as I write these lines, a .heic file cannot be displayed in virtually any browser. Safari excepted, of course.
Apple knows Apple’s quirks. This is the same mechanism I described in My smartphone, their dictatorship: everything is seamless as long as you stay inside the walled garden, and the moment you step off the paved path, you pay for it. When a user uploads a photo straight from Safari on an iPhone, the browser converts it to .jpg on the fly and nobody notices a thing. The trouble starts the moment you leave that path: the member copies the .heic files to a computer, then uploads them from Firefox or Chrome. The file lands on the server exactly as it is, in a format neither the browser nor the forum knows how to display.
From an administrator’s chair, the result looks a lot like what I described about bulk uploads in Gutenberg: a stream of images that ought to be trivial, and that turns into a daily source of incidents.
On the Invision Community 5 side, the diagnosis is straightforward: \IPS\Image::create() identifies images by their magic bytes, and recognizes neither HEIC nor HEIF. The file is therefore stored as an ordinary attachment rather than an image. Hence the download link.
The setting I refused to impose
There is a workaround on the iPhone: Settings, Camera, Formats, “Most Compatible.” The phone then shoots in JPEG and the problem goes away.
Except no. My communities were seeing hundreds of .heic files arrive every day, sent by members who have no idea the format even exists. I could hardly picture myself pinning an announcement explaining to each of them how to change a setting buried deep in their phone so their photos would be “more compatible.” It is not up to members to work around the limits of the software. It is up to the software to do its job.
No such application existed for Invision Community 5. So I built one.
HEIC Uploads
HEIC Uploads converts members’ HEIC and HEIF photos in the background into a format the forum can display, without ever blocking the post from going through. The member posts as usual; a scheduled task picks up the files in question, converts them, flips the attachment over to an image and, if the post went live in the meantime, rewrites its HTML to insert the image tag. Attachments that predate the install are never touched.
The conversion engine was not much of a debate: ImageMagick through the imagick extension, the only thing in PHP that can both decode HEIC and encode AVIF. It happens to be exactly the kind of decision we rarely make consciously, even though everything downstream depends on it.
The output format, on the other hand, held a surprise. I expected to go with WebP, the safe bet. The measurements decided otherwise: on a 12-megapixel iPhone photo, AVIF produces a file of roughly 90 KB where WebP weighs in at 500, and encodes it four times faster. A format that is both faster and five times lighter leaves no trade-off to weigh. The forum benefits along the way: the original HEIC’s 2.1 MB become 90 KB served to visitors.
A few deliberate choices are worth spelling out:
- The original HEIC is deleted after conversion. This is intentional, and documented in bold: back up your uploads directory before installing.
- The application refuses to install if the server cannot convert (PHP 8.1, the imagick extension, ImageMagick compiled with libheif and an AVIF delegate), and tells you precisely what is missing. No silently inoperative install.
- Six command-line tools ship with it, among them a
selftest.phpthat replays the conversion of a problematic file with no forum and no database, and adiagnose.phpthat pinpoints a failure in six steps.
In production
The application has been running in production on a real forum since August 10: 191 conversions, zero failures, the chain validated from upload to display, post rewriting included. Version 1.0.1, released today after a full audit, fixes the known limitations of 1.0.0 and closes two security gaps.
The whole thing is published under the MIT license, which remains my way of giving back to the commons what the commons gave me, translated into five languages, and available on GitHub. Bug reports are welcome, ideally with the output of diagnose.php attached.
Your members have nothing to change on their iPhones. And that is exactly how it should be.