ioshevcheif

What's the formal way to verify if my device is capable of encoding images in HEIC format?


I'm trying to save an image in the HEIC file format using ImageIO. The code looks something like this:

NSMutableData *imageData = [NSMutableData data];

CGImageDestinationRef destination = CGImageDestinationCreateWithData(
    (__bridge CFMutableDataRef)imageData,
    (__bridge CFStringRef)AVFileTypeHEIC, 1, NULL);
if (!destination) {
  NSLog(@"Image destination is nil");
  return;
}

// image is a CGImageRef to compress.
CGImageDestinationAddImage(destination, image, NULL);
BOOL success = CGImageDestinationFinalize(destination);
if (!success) {
  NSLog(@"Failed writing the image");
  return;
}

This works on devices with A10, but fails on older devices and on the simulator (also according to Apple), by failing to initialize the destination and the error message findWriterForType:140: unsupported file format 'public.heic'. I couldn't find any direct way to test if the hardware supports HEIC without initializing a new image destination and testing for nullability.

There are AVFoundation-based APIs for checking if photos can be saved using HEIC, for example using -[AVCapturePhotoOutput supportedPhotoCodecTypesForFileType:], but I don't want to initialize and configure a capture session just for that.

Is there a more direct way to see if the hardware supports this encoding type?


Solution

  • ImageIO has a function called CGImageDestinationCopyTypeIdentifiers which returns a CFArrayRef of the supported types for CGImageDestinationRef. Therefore, the following code can be used to determine whether HEIC encoding is supported on the device:

    #import <AVFoundation/AVFoundation.h>
    #import <ImageIO/ImageIO.h>
    
    BOOL SupportsHEIC() {
      NSArray<NSString *> *types = CFBridgingRelease(
          CGImageDestinationCopyTypeIdentifiers());
      return [types containsObject:AVFileTypeHEIC];
    }