November 25, 2023
Converting HEICs to JPGs, as well as automatic detection of mislabeled JPGs is now free with s3.fm.
What is an HEIC and why should I be concerned about them?
An HEIC is a proprietary image format native to Apple iPhones. The acronym “HEIC” stands for “High Efficiency Image Compression.” While having your own bespoke image format is cool and probably makes the pictures on your iPhone really pop, it has some drawbacks. Many Apple products have long been famously incompatible with everything else, and HEIC images are no exception. Here are a few things that won’t work with HEICs:
- FileMaker’s interactive containers
- Nearly all modern web browsers except Safari
- Most image editing software (paint.net, Adobe photoshop, etc)
- Almost anything else that displays an image and isn’t made by Apple
This can be a problem if your users have iPhones as their primary cameras. Even the most fastidious users will have issues keeping their iPhones set to Settings > Camera > Formats > Most Compatible. It takes too many clicks to set, sometimes it doen’t stick through an iOs or hardware upgrade, or the user borrows a phone because they’re out of juice. You just can’t depend on humans to check a setting buried 6 clicks deep each time they’re taking a photo for your website or FileMaker.
How can I tell if I have an HEIC in one of my FileMaker containers?
In an interactive FM container, HEICs are often displayed as a blank container. Alternatively, they can show up like a bunch of spattered dots too (see above).
How can I tell if I have an HEIC on my website?
An HEIC usually displays as a “broken image” icon on a website.
I have found a bunch of HEIC images that are labeled as JPGs. What gives?
This is a problem we’ve also found with certain combinations of devices and apps, especially in FileMaker Go. The most common way to re-create this bug is as follows:
- The user takes a photo on their iPhone.
- The user uses iCloud or AirDrop to move the image to another device (usually an iPad).
- The user inserts the image in a container in FileMaker Go from the camera roll of the 2nd device.
- The HEIC image is uploaded to FileMaker Server with a filename ending in .JPG instead of .HEIC, despite not having converted any of the data in the underlying file to a jpeg.
This is not ideal, as the file extension must match the encoding of the underlying data for anything meaningful to be displayed. Because the image viewer software is trying to display a JPG and the file isn’t actually a JPG, it displays incorrectly and the user sees nothing, a bunch of dots, or a broken image.
How does s3.fm identify HEICs?
First, s3.fm only checks for HEICs when you choose a destination filename that ends in jpg or jpeg. In other words, if you’re trying to upload a file to S3 and name it with the extension .wav or .mov, s3.fm won’t check if it’s an HEIC. If you do use a .jpg or .jpeg as the extension, however, s3.fm will check the underlying file to see if it is actually an HEIC. How does it do that? Well, files that are HEICs have a specific signature at the beginning that reads “ftypheic”. s3.fm reads the first few bytes of the file, checking for this signature. If the signature is detected, s3.fm can do one of two things depending on what payload options you sent it. It can either just let you know that the file is actually an HEIC, or it can convert the file to a JPG.
What is the default behavior of s3.fm regarding conversion?
The default is for the images to NOT be converted, and for s3.fm to simply notify you of the problem in its API response. If an HEIC is detected, the response from s3.fm will include a key-value pair of “isHEIC: true”, like this:
{"URL" : "https://s3fm-test-bucket-2023.s3.us-east-1.amazonaws.com/Photo 5-2-2023 5.42.35 AM.jpg",
"httpStatus" : 200,
"isHEIC" : true,
"message" : "ok",
"s3UploadResponse" : {"ETag" : "\"65adac016331a74dacc4211120250b02\"",
"ServerSideEncryption" : "AES256" } }
How do I set my uploads to be converted if an HEIC is detected?
If you want to enable automatic conversion of any HEICs to JPGs, all you need to do is add this line somewhere to your SetJSONElement in your $payload:
[ "s3.convertHEIC" ; True ; 5 ] ;
So for example, here’s a Set Variable script step for a $payload.
JSONFormatElements (
JSONSetElement ( "" ;
/* REQUIRED FIELDS */
[ "fm.FQDN" ; "yourserver.domain.com" ; 1 ] ;
[ "fm.database" ; "yourDatabase" ; 1 ] ;
[ "fm.responseField" ; "uploadedURL" ; 1 ] ;
[ "fm.container.field" ; "container" ; 1 ] ;
[ "fm.container.layout" ; "files" ; 1 ] ;
[ "fm.container.key.field" ; "PrimaryKey" ; 1 ] ;
[ "fm.container.key.value" ; files::PrimaryKey ; 1 ] ;
/* NOT REQURIED FOR TRIAL SUBSCRIPTIONS */
[ "s3.region" ; "us-east-1" ; 1 ] ;
[ "s3.bucket" ; "yourbucket" ; 1 ] ;
[ "s3.key" ; GetContainerAttribute ( files::container ; "filename" ) ; 1 ] ;
[ "s3.makePublic" ; "1" ; 5 ] ;
[ "s3.mime" ; "image/jpeg" ; 1 ] ;
[ "s3.convertHEIC" ; True ; 5 ] ;
/* OPTIONAL FIELDS */
[ "fm.log.field" ; "" ; 1 ] ;
[ "fm.log.layout" ; "" ; 1 ]
)
)
This will also add two key value pairs to the API response: isHEIC and wasHEIC. isHEIC will be false, as the HEIC is no longer an HEIC. wasHEIC will be true, as the conversion was completed from HEIC to JPG. Like this:
{"URL" : "https://yourbucket.s3.us-east-1.amazonaws.com/sadeggsde.jpg",
"httpStatus" : 200,
"isHEIC" : false,
"message" : "ok",
"s3UploadResponse" : {"ETag" : "\"596cbd3971fef7426a25407bcb8290d6\"",
"ServerSideEncryption" : "AES256" },
"wasHEIC" : true }
Does it cost anything extra to do the conversion?
Nope! You’ll only be charged for a single write, just as if you were uploading any other kind of file.
Wow, that’s awesome. What should I do about files that I’ve already uploaded?
Currently, there isn’t an endpoint to read if a previously uploaded .jpg or .jpeg file is actually an HEIC. However, if there is enough interest, Sully might add one. Send him an email and let him know you want that endpoint, and he’ll set you up if you need one.