CGImageDestinationFinalize or UIImageJPEGRepresentation - Crash when saving a large file on IOS 10

半城伤御伤魂 提交于 2019-12-22 10:33:46

问题


I am trying to create tiles for a larger image, and it seems that as of IOS 10 the following code no longer works and crashes with EXC_BAD_ACCESS.

This happens on IOS 10 Device only, IOS 9 works fine.

The crash happens with any image that is larger than ~1300x1300.

Profiling in instruments doesn't yield anything interesting and points to CGImageDestinationFinalize.

There is no memory spike.

I tried both ways below:

UIImage* tempImage = [UIImage imageWithCGImage:tileImage];
NSData*  imageData = UIImageJPEGRepresentation(tempImage, 0.8f); // CRASH HERE.

OR

+ (BOOL) CGImageWriteToFile: (CGImageRef) image andPath: (NSString *)path
{
    CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:path];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL);
    if (!destination) {
        NSLog(@"Failed to create CGImageDestination for %@", path);
        return NO;
    }

    CGImageDestinationAddImage(destination, image, nil);

    if (!CGImageDestinationFinalize(destination)) { // CRASH HERE
        NSLog(@"Failed to write image to %@", path);
        CFRelease(destination);
        return NO;
    }

    CFRelease(destination);

As I understand it UIImageJPEGRepresentation in turn calls CGImageDestinationFinalize eventually.

Edit: Forgot to mention the images are written to hdd, but about half way through.

This really does seem like something to do with IOS 10, could this be a bug?

I also filed the bug with apple just in case.

Any help or workarounds on how to write out large images is greatly appreciated.


回答1:


I am going to answer my own question here.

What I have gathered is that IOS 10 has trouble saving a file that has color mode "grayscale".

So if you do

UIImageJPEGRepresentation(tempImage, 0.8f)

and if tempImage is grayscale you will get a crash.

I was processing many images and it didn't click until later that it could be related to the color mode of the image.

I already filed a bug with apple to see what they say, but meanwhile I had to find a temporary fix.

My fix was to convert image to RGB by drawing it and capturing it into a new image.

Sample method:

+ (UIImage *)convertImage:(UIImage *)sourceImage
{
    UIGraphicsBeginImageContext(sourceImage.size);
    [sourceImage drawInRect:CGRectMake( 0, 0, sourceImage.size.width, sourceImage.size.height)];

    UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return targetImage;
}

Hopefully this helps someone.




回答2:


  1. tempimage is one of the parameters you passed to UIImageJPEGRepresentation; if it points to a dead object, then that will cause a crash when UIImageJPEGRepresentation tries to use that dead object. check whether tempImage is nil.
  2. check whether you are adding image after calling CGImageDestinationFinalize at destination


来源:https://stackoverflow.com/questions/39710875/cgimagedestinationfinalize-or-uiimagejpegrepresentation-crash-when-saving-a-la

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!