【发布时间】:2015-06-09 01:57:08
【问题描述】:
假设您从 UIImage 开始,并且希望裁剪它。最常见的方法是使用 CGImageCreateWithImageInRect 获取 CGImageRef 并从中创建新图像,如下所示:
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
现在假设您稍后需要将此 UIImage 转换为 NSData 对象。例如,如果您希望使用 NSKeyedArchiver 将图像存储在磁盘上,就会发生这种情况。或者,您可以通过显式执行以下操作来获取 NSData 对象:
NSData *imageData = UIImagePNGRepresentation(croppedImage);
我这样做了,后来我尝试通过这样做来重建一个新的 UIImage 对象:
UIImage *image = [UIImage imageWithData:imageData];
我为一系列 48 张图片执行此操作。它们中的大多数都很好,但是在每 4 张图像之后,接下来的 2 张图像被损坏,每张图像的顶部和底部都被交换了。如果我取出转换为 NSData 并再次返回,它工作正常。如果我使用 NSKeyedArchiver 将图像数组写入磁盘(我猜在其编码例程中调用 UIImagePNGRepresentation 之类的东西),我也会遇到完全相同的问题。我的理论是这一定与我如何从 CGImageRefs 构建图像有关。
解决方法是什么?我似乎无法弄清楚如何将 CGImageRefs 放入 NSData 对象中,我更喜欢正确构建 UIImage 以便它可以被序列化的解决方案。
编辑:
有些人要求实际运行的代码,所以我在这里添加它
UIImage *image = self.animationObject.image;
for (int y=0; y<[self.animationInfoObject.numInY intValue]; y++) {
for (int x=0; x<[self.animationInfoObject.numInX intValue]; x++) {
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
NSData *imageData = UIImageJPEGRepresentation(croppedImage, 1.0);
[self addImageToArray:imageData];
CFRelease(imageRef);
}
}
self.animationObject.image 中的图像是一个图像网格,每个方向都有 numInX 和 numInY 个图像。我从 2D 网格中裁剪出每个单独的图像并保存它们。
稍后,我将图像放在图像视图中以对其进行动画处理。代码如下:
NSMutableArray *animationArray = [[NSMutableArray alloc] init];
for (int frame=0; frame<[[photoObject frameArray] count]; frame++) {
NSData *imageData =[[photoObject imageArray] objectAtIndex:[[[photoObject frameArray] objectAtIndex:frame] integerValue]-1];
UIImage *image = [UIImage imageWithData:imageData];
[animationArray addObject:image];
}
这一切在 iPhone 6 上都可以正常工作,但在 iPhone 5 上却不行。这似乎也只是在图像网格很长时才会出现问题。例如,对于我使用 self.animationObject.image 的示例,numInY 为 3,numInX 为 2,图像的总大小为 1536x3072(每个迷你图像为 768x1024)。顶部和底部翻转的是底部的两张图像。
【问题讨论】:
-
一些更有用的细节。我有合成图像,每个图像在 2x3 网格中包含 6 个较小的图像。每张图像的大小为 768x1024,因此合成图像的总大小为 1536x3072。这是每个合成中的第 5 和第 6 个图像,它们的下半部分和上半部分交换了。因此,裁剪到大图像底部的 CGImage 有一些奇怪的地方,也许?再次,我应该提到,如果 UIImage 没有转换为 NSData 然后再返回,这将非常有效。
-
所以在上面的这个例子中,宽度是 768,高度是 1024,当 x 为 0 或 1 并且 y 为 2 时它会中断。当 y 为 0 或 1 时它工作正常。这是一种情况CGImageCreateWithImageInRect 就不能处理那么大的图片?
-
很难看出是什么原因造成的。我建议将其打包为测试应用程序并在 bugreporter.apple.com 上提交雷达。或者,如果您有 DTS 事件空闲,请由他们运行它以希望得到解决。
-
@Mike 您能否分享更多代码并分享一些测试图像,以便我们在这里进行测试?
-
我同意@Mike,你能用代码说明你是如何在 48 张图片上循环的吗?
标签: ios objective-c uiimage nsdata cgimageref