CG光栅数据对于一个图像太大

问题描述:

我试图旋转用相机拍摄的2448x3264的UIImage。当我这样做时,内存大约120Mb,大致3/4秒,然后恢复到正常状态。问题在于,在内存较少的设备(例如ipod touch)中,应用程序崩溃。即使没有,我也不认为它应该为一张图片使用那么多的内存。发生这种情况时,Iphone 5也落后了。CG光栅数据对于一个图像太大

根据this回答一个评论,使用UIGraphicsGetCurrentContext()应该是宽度之后在所述解压缩存储器的字节大小×高度×CGImageGetBitsPerComponent(image.CGImage)/ 8个字节,因此图像应占据8MB,不120 。

任何想法为什么发生这种情况,以及如何解决它?

这里的UIImage的caterogy方法返回一个旋转的图像:

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees { 
    CGFloat radian = (CGFloat) (degrees * (M_PI/ 180.0f)); 
    CGSize rotatedSize = [self rotatedImageSize:degrees]; 

    // Create the bitmap context 
    UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 0); 
    CGContextRef bitmap = UIGraphicsGetCurrentContext(); 

    CGPoint contextCenter = CGPointMake(rotatedSize.width/2.0f, 
rotatedSize.height/2.0f); 
    CGContextTranslateCTM(bitmap, contextCenter.x, contextCenter.y); 

    // // Rotate the image context 
    CGContextRotateCTM(bitmap, radian); 
    // Now, draw the rotated/scaled image into the context 
    [self drawInRect:CGRectMake(-self.size.width/2.0f, - 
self.size.height/2.0f, self.size.width, self.size.height)]; 

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 

下面是仪器证明栅格数据是什么导致内存高峰期,只是在执行rotate方法:

​​

的几点意见:

  • 2448x3264x(比如4个字节/像素)约为30兆字节。
  • 不要旋转它。如果它正在屏幕上显示,则可以使用视图的transform属性。如果它进入一个文件,并且旋转是8个exif方向之一,则编写说明哪个方向的元数据。同样,如果它来自文件,请使用Image I/O并请求CGImageSourceRef生成一个您需要将其放在屏幕上的大小的定向缩略图。 (提示使用kCGImageSourceThumbnailMaxPixelSize和kCGImageSourceCreateThumbnailWithTransform。)对于任意角度,您可以使用CoreImage过滤器,该过滤器可以将图像旋转并缩减为屏幕所需的大小(在GPU上)。同样,您可以使用vImage在CPU上执行相同的操作(提示vImageAffineWarpCG_ARGB8888)。 vImage速度非常快,它可以为您提供比核心图形更好的重采样。等等...如果它伤害,不要这样做。
  • 在将角度转换为旋转矩阵之前,您应该暂停。例如,如果你的角度是90度,你想要的矩阵就是[0 1 -1 0 0 0],并且你的重采样代码比你计算的近似结果更快乐。旋转矩阵是[cos(t)sin(t)-sin(t)cos(t)0 0]。客户可能已经可以直接通过余弦和正弦。