Heic format image incompatibility issue

I am a developer working on iOS apps.

In the demo, I planned to replace the local images with Heic format instead of PNG format, but the actual test results showed abnormalities on this device, while the other test devices displayed normally

Heic images are converted by the built-in image conversion function on Mac. I tested multiple Heic images, but none of them were displayed and the image information returned nil,,but PNG images can be displayed normally.

device information:

Hello. HEIC has been around since iOS 11 so I don't expect any issues displaying on that system software version. Are they large images? How are you converting your files? Can you explain more about what you mean by "image information"?

I tested many devices and the results are as follows:

Thanks for showing your test results. Can you provide more information about what kinds of tests you used? What kinds of error messages/diagnostic information were you able to find in the case where your tests failed?

I recorded a video, but I found that the video cannot be uploaded.

This is my test code:

UIImage *i = [UIImage imageNamed:@"temp"];
NSLog(@"%@", i);
UIImageView *v = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"temp"]];
[self.view addSubview:v];
v.frame = CGRectMake(50, 150, 300, 200);

iPhone 8 plus, iOS 12.1.1 output:

2024-10-21 11:05:36.699573+0800 temp-02[1226:204265] (null)

other devices outputs:

<UIImage:0x600003014120 named(main: temp) {132.66666666666666, 122} renderingMode=automatic(original)>

In the Xcode project, first decode PNG images and then re encode them into heic images, which can be successfully displayed on iPhone 8 plus and iOS 12.1.2;

Is it a problem with the Mac conversion tool or other issues? Is there a better conversion compatibility solution for PNG to heic? thank you.

The conversion code is as follows:

- (void)test3{
    NSString *url = [[NSBundle mainBundle] pathForResource:@"1-m" ofType:@"png"];
    CGImageRef ref = createCGImageFromFile(url);
    
    NSString *path_document = NSHomeDirectory();
    NSString *imagePath = [path_document stringByAppendingString:@"/Documents/pic.heic"];
    [self generateNewHEIC:[UIImage imageWithCGImage:ref] savePath:imagePath];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        UIImage *i = [[UIImage alloc] initWithContentsOfFile:imagePath];
        NSLog(@"%@", i);
        UIImageView *v = [[UIImageView alloc] initWithImage:i];
        [self.view addSubview:v];
        v.frame = CGRectMake(50, 150, 300, 200);
        
    });
    
    CFRelease(ref);
}

/// create CGImageRef
/// - Parameter path: main bundle
CGImageRef createCGImageFromFile (NSString* path)
{
    // Get the URL for the pathname passed to the function.
    NSURL *url = [NSURL fileURLWithPath:path];
    CGImageRef        myImage = NULL;
    CGImageSourceRef  myImageSource;
    CFDictionaryRef   myOptions = NULL;
    CFStringRef       myKeys[2];
    CFTypeRef         myValues[2];

    // Set up options if you want them. The options here are for
    // caching the image in a decoded form and for using floating-point
    // values if the image format supports them.
    myKeys[0] = kCGImageSourceShouldCache;
    myValues[0] = (CFTypeRef)kCFBooleanTrue;
    myKeys[1] = kCGImageSourceShouldAllowFloat;
    myValues[1] = (CFTypeRef)kCFBooleanTrue;
    // Create the dictionary
    myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
                   (const void **) myValues, 2,
                   &kCFTypeDictionaryKeyCallBacks,
                   & kCFTypeDictionaryValueCallBacks);
    // Create an image source from the URL.
    myImageSource = CGImageSourceCreateWithURL((CFURLRef)url, myOptions);
    CFRelease(myOptions);
    // Make sure the image source exists before continuing
    if (myImageSource == NULL){
        fprintf(stderr, "Image source is NULL.");
        return  NULL;
    }
    // Create an image from the first item in the image source.
    myImage = CGImageSourceCreateImageAtIndex(myImageSource, 0, NULL);

    CFRelease(myImageSource);
    // Make sure the image exists before continuing
    if (myImage == NULL){
         fprintf(stderr, "Image not created from image source.");
         return NULL;
    }

    return myImage;
}


///
/// - Parameters:
///   - image: <#image description#>
///   - path: <#path description#>
- (void)generateNewHEIC:(UIImage *)image savePath:(NSString *)path{
    
    NSMutableData *imageData = [NSMutableData data];
    // HEIC
    CFStringRef imageUTType =  CFSTR("public.heic");
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL);
    if (!destination) {
        return;
    }
    CGImageRef imageRef = image.CGImage;
    CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationDown;
    NSMutableDictionary *frameProperties = [NSMutableDictionary dictionary];
//    imageProperties[(__bridge_transfer NSString *) kCGImagePropertyExifDictionary] = @(exifOrientation);
    CGImageDestinationAddImage(destination, imageRef, (__bridge CFDictionaryRef)frameProperties);
    if (CGImageDestinationFinalize(destination) == NO) {
        imageData = nil;
    }
    CFRelease(destination);
    if(imageData) {
        NSURL *url = [NSURL fileURLWithPath:path];
        [imageData writeToURL:url atomically:YES];
    }
}

I don't know if it's related, but in a test project I'm using to try out text recognition from photos Xcode does not recognise .HEIC as a valid extension for images in the Asset catalogue. Changing (in Finder's Get Info) the extension to .heic (i.e. lowercase) solves the issue. A device/app interoperability issue methinks..... Images from my iPhone and iPad all have the .HEIC extension, which (of course) doesn't get changed to lowercase on Airdrop to my Mac.

I'm using Xcode 16.2 Beta 2 with iOS devices on 18.2 and Mac on 15.2.

Regards, Michaela

Heic format image incompatibility issue
 
 
Q