2011-06-30 24 views
1

我有一个“ImageManipulator”类,用于在iPhone上执行一些裁剪,调整大小和旋转相机图像。在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大小,我仍然看到了尖峰我以后想知道是否有是一种不同的/更有效的方式来完成上述的旋转?

在此先感谢您的回复。 Rog

+0

图像有多大?我们有类似的问题,所以我们首先将图像缩放到可接受的尺寸,然后应用旋转。 –

+0

您是否在冗长的操作中创建大型自动释放对象? – Eiko

+2

内存尖峰是因为'CGBitmapContextCreate'必须分配一个缓冲区来保存图像数据,这将是关于'width * height * CGImageGetBitsPerComponent(self.CGImage)/ 8'字节。如果需要在绘制原始图像之前加载或解压缩原始图像的图像数据,'CGContextDrawImage'也可能分配另一个相似大小的缓冲区。不过,我不知道更有效的方法。 – Anomie

回答

1

如果您要保存为JPEG格式,我想另一种方法是按原样保存图像,然后通过操纵EXIF元数据将旋转设置为任何您想要的值。见例如this post。简单但可能有效,即使你必须在内存中保存图像有效负载字节)

0
  • 您是否尝试过检查内存泄漏并分析分配?
  • 如果图像仍然太大,请尝试将图像分片而不是整体旋转。
-1

由于Anomie提到,CGBitmapContextCreate创建了一个上下文。我们应该通过使用释放

CGContextRelease(ctx); 

如果您有使用创建或复制创建的任何其他对象,也应该释放。如果是CFData,然后

CFRelease(cfdata); 
1

事情可以做:

  1. 比例缩小的图像更(你可能不希望)

  2. 记住释放一切,一旦你完成它

  3. 住它

我会选择选项2和3

图像编辑非常耗费资源,因为它加载整个原始未压缩的图像数据转换成用于处理内存。这是不可避免的,因为除了将完整的原始数据加载到内存之外,绝对没有其他方式来修改映像。除非应用程序收到内存警告,否则内存消耗尖峰并不重要,在这种情况下,在崩溃之前快速清除所有内容。但是,很少会发生内存警告,因为我的应用程序会定期将单个> 10 MB的文件加载到内存中,即使在较旧的设备上,我也不会收到警告。所以你会很好的尖峰。

相关问题