CGImageDestinationFinalize 或 UIImageJPEGRepresentation - 在 IOS 10 上保存大文件时崩溃
CGImageDestinationFinalize or UIImageJPEGRepresentation - Crash when saving a large file on IOS 10
我正在尝试为更大的图像创建图块,似乎从 IOS 10 开始,以下代码不再有效并因 EXC_BAD_ACCESS 而崩溃。
这只发生在 IOS 10 设备上,IOS 9 工作正常。
任何大于 ~1300x1300 的图像都会发生崩溃。
仪器中的分析没有产生任何有趣的东西,并指向 CGImageDestinationFinalize。
没有内存峰值。
我尝试了以下两种方法:
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);
CFRelease(destination);
return NO;
}
CFRelease(destination);
据我了解,UIImageJPEGRepresentation 最终又会调用 CGImageDestinationFinalize。
编辑:忘记提及图像已写入硬盘,但大约写入了一半。
这看起来确实与 IOS10 有关,这可能是一个错误吗?
为了以防万一,我也向苹果提交了错误。
非常感谢任何有关如何写出大图像的帮助或解决方法。
tempimage
是你传递给UIImageJPEGRepresentation
的参数之一;如果它指向一个死对象,那么当 UIImageJPEGRepresentation
尝试使用该死对象时将导致崩溃。检查 tempImage
是否为零。
- 检查在目的地
CGImageDestinationFinalize
调用CGImageDestinationFinalize
后是否添加图像
我要在这里回答我自己的问题。
我收集到的是 IOS 10 无法保存颜色模式为“灰度”的文件。
所以如果你这样做
UIImageJPEGRepresentation(tempImage, 0.8f)
如果 tempImage 是灰度,你会遇到崩溃。
我处理了很多图片,后来一直点不出来,可能和图片的颜色模式有关。
我已经向 apple 提交了一个错误,看看他们怎么说,但同时我必须找到一个临时修复程序。
我的解决方法是通过绘制图像并将其捕捉到新图像中,将图像转换为 RGB。
示例方法:
+ (UIImage *)convertImage:(UIImage *)sourceImage
{
UIGraphicsBeginImageContext(sourceImage.size);
[sourceImage drawInRect:CGRectMake( 0, 0, sourceImage.size.width, sourceImage.size.height)];
UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return targetImage;
}
希望这对某人有所帮助。
我正在尝试为更大的图像创建图块,似乎从 IOS 10 开始,以下代码不再有效并因 EXC_BAD_ACCESS 而崩溃。
这只发生在 IOS 10 设备上,IOS 9 工作正常。
任何大于 ~1300x1300 的图像都会发生崩溃。
仪器中的分析没有产生任何有趣的东西,并指向 CGImageDestinationFinalize。
没有内存峰值。
我尝试了以下两种方法:
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);
CFRelease(destination);
return NO;
}
CFRelease(destination);
据我了解,UIImageJPEGRepresentation 最终又会调用 CGImageDestinationFinalize。
编辑:忘记提及图像已写入硬盘,但大约写入了一半。
这看起来确实与 IOS10 有关,这可能是一个错误吗?
为了以防万一,我也向苹果提交了错误。
非常感谢任何有关如何写出大图像的帮助或解决方法。
tempimage
是你传递给UIImageJPEGRepresentation
的参数之一;如果它指向一个死对象,那么当UIImageJPEGRepresentation
尝试使用该死对象时将导致崩溃。检查tempImage
是否为零。- 检查在目的地
CGImageDestinationFinalize
调用CGImageDestinationFinalize
后是否添加图像
我要在这里回答我自己的问题。
我收集到的是 IOS 10 无法保存颜色模式为“灰度”的文件。
所以如果你这样做
UIImageJPEGRepresentation(tempImage, 0.8f)
如果 tempImage 是灰度,你会遇到崩溃。
我处理了很多图片,后来一直点不出来,可能和图片的颜色模式有关。
我已经向 apple 提交了一个错误,看看他们怎么说,但同时我必须找到一个临时修复程序。
我的解决方法是通过绘制图像并将其捕捉到新图像中,将图像转换为 RGB。
示例方法:
+ (UIImage *)convertImage:(UIImage *)sourceImage
{
UIGraphicsBeginImageContext(sourceImage.size);
[sourceImage drawInRect:CGRectMake( 0, 0, sourceImage.size.width, sourceImage.size.height)];
UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return targetImage;
}
希望这对某人有所帮助。