问题
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:
tempimage
is one of the parameters you passed toUIImageJPEGRepresentation
; if it points to a dead object, then that will cause a crash whenUIImageJPEGRepresentation
tries to use that dead object. check whethertempImage
is nil.- check whether you are adding image after calling
CGImageDestinationFinalize
at destination
来源:https://stackoverflow.com/questions/39710875/cgimagedestinationfinalize-or-uiimagejpegrepresentation-crash-when-saving-a-la