Electrik Bunny Electrik Bunny - 1 year ago 220
iOS Question

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

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.


+ (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);
return NO;


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.

Answer Source

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
    [sourceImage drawInRect:CGRectMake( 0, 0, sourceImage.size.width, sourceImage.size.height)];

    UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();

    return targetImage;

Hopefully this helps someone.