在 iPhone 上调整图像大小、旋转和裁剪图像时内存消耗激增
我有一个“ImageManipulator”类,可以在 iPhone 上对相机图像执行一些裁剪、调整大小和旋转操作。
目前,一切都按预期进行,但我的内存消耗不断出现一些巨大的峰值,这有时会导致应用程序崩溃。
我已设法将问题隔离到代码的一部分,在该部分代码中检查当前图像方向属性并将其相应地旋转到 UIImageOrientationUp
。然后,我从位图上下文中获取图像并将其保存到磁盘。
这就是我目前正在做的事情:
CGAffineTransform transform = CGAffineTransformIdentity;
// Check for orientation and set transform accordingly...
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
// Create a bitmap context with the image that was passed so we can perform the rotation
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
// Rotate the context
CGContextConcatCTM(ctx, transform);
// Draw the image into the context
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
// Grab the bitmap context and save it to the disk...
即使在尝试将图像缩小到尺寸的一半甚至 1/4 之后,我仍然看到尖峰,我想知道是否有不同/更有效的方法来获得旋转如上所述完成吗?
预先感谢您的回复。 罗格
I have an "ImageManipulator" class that performs some cropping, resizing and rotating of camera images on the iPhone.
At the moment, everything works as expected but I keep getting a few huge spikes in memory consumption which occasionally cause the app to crash.
I have managed to isolate the problem to a part of the code where I check for the current image orientation property and rotate it accordingly to UIImageOrientationUp
. I then get the image from the bitmap context and save it to disk.
This is currently what I am doing:
CGAffineTransform transform = CGAffineTransformIdentity;
// Check for orientation and set transform accordingly...
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
// Create a bitmap context with the image that was passed so we can perform the rotation
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
// Rotate the context
CGContextConcatCTM(ctx, transform);
// Draw the image into the context
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
// Grab the bitmap context and save it to the disk...
Even after trying to scale the image down to half or even 1/4 of the size, I am still seeing the spikes to I am wondering if there is a different / more efficient way to get the rotation done as above?
Thanks in advance for the replies.
Rog
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您要保存为 JPEG,我想另一种方法是按原样保存图像,然后通过操作 EXIF 元数据将旋转设置为您想要的任何内容?例如,请参阅这篇文章。简单但可能有效,即使您必须将图像有效负载字节保存在内存中;)
If you are saving to JPEG, I guess an alternative approach is to save the image as-is and then set the rotation to whatever you'd like by manipulating the EXIF metadata? See for example this post. Simple but probably effective, even if you have to hold the image payload bytes in memory ;)
你可以做的事情:
进一步缩小图像(你可能不想要)
记住将所有内容释放为一旦你完成它
与它共存
我会选择选项2和3。
图像编辑是非常资源密集型的,因为它将整个原始未压缩图像数据加载到内存中进行处理。这是不可避免的,因为除了将完整的原始数据加载到内存中之外,绝对没有其他方法可以修改图像。内存消耗峰值并不重要,除非应用程序收到内存警告,在这种情况下,在崩溃之前快速清除所有内容。不过,您很少会收到内存警告,因为我的应用程序会定期加载单个 > > 。 10 mb 文件放入内存中,即使在较旧的设备上,我也没有收到警告。所以你可以放心使用尖刺。
Things you can do:
Scale down the image even more (which you probably don't want)
Remember to release everything as soon as you finish with it
Live with it
I would choose option 2 and 3.
Image editing is very resource intensive, as it loads the entire raw uncompressed image data into the memory for processing. This is inevitable as there is absolutely no other way to modify an image other than to load the complete raw data into the memory. Having memory consumption spikes doesn't really matter unless the app receives a memory warning, in that case quickly get rid of everything before it crashes. It is very rare that you would get a memory warning, though, because my app regularly loads a single > 10 mb file into the memory and I don't get a warning, even on older devices. So you'll be fine with the spikes.
正如 Anomie 提到的,CGBitmapContextCreate 创建一个上下文。我们应该通过使用来释放它。
如果您有使用 create 或 copy 创建的任何其他对象,那么也应该释放它。如果是CFData,那么
As Anomie mentioned, CGBitmapContextCreate creates a context. We should release that by using
If you have any other objects created using create or copy, that should also be released. If it is CFData, then