CGGraphics内存和优化问题

时间:2014-01-18 06:09:04

标签: ios memory optimization cgimage

目的

我正在开发一个实用程序,用于根据任意宽高比裁剪UIImageaspectFitaspectFill作为裁剪选项。 aspectFill选项将裁剪原始图像,使最终图像完全被原始图像覆盖。 aspectFit将确保不会剪切原始图像的像素,并且将黑色条纹添加到原始图像的两侧以使其适合宽高比。我知道已经有第三方图书馆做同样的工作,但我想把它作为一个学习练习。

我的方法

  • 对于aspectFill,我只是计算最终图像偏移量和大小,并从原始CGRect中裁剪UIImage
  • 对于aspectFit,我会计算最终图片尺寸,然后使用CGContextRef制作一个CGContextFillRect。在这种情况下,我在所需的偏移处绘制原始图像(将原始图像保留在最终图像的中间)。

问题

要测试此实用程序,我使用的是 2MB 图像,其大小与iPhone相机照片大致相同。出现了以下问题:

  • aspectFill的实用程序按预期工作,每个图像处理 0.01ms 处理时间,这很好。问题是,如果我尝试在循环中运行此实用程序以获取大量图像(10000 +),则内存使用量会激增,直到应用程序崩溃。我添加了@autoreleasepool块,但似乎没有任何区别。

  • aspectFit实用程序存在相反的问题。此处的@autoreleasepool块按预期工作,并定期释放对象,以便应用程序不会因循环中的任意数量的图像而崩溃。但在这里,每张图片的处理时间都在 130ms 左右,这似乎很多。我尝试使用UIGraphicsBeginImageContext代替CGContextRef,但这需要花费更多时间。

代码

aspectFill的代码

//ox, oy are the image crop offsets calculated before and fw, fh are the width and height of final image

@autoreleasepool {
    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(ox,oy,fw,fh));
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return finalImage;
}     

aspectFit的代码

@autoreleasepool {
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
    CGContextRef context = CGBitmapContextCreate(NULL, fw, fh, CGImageGetBitsPerComponent(image.CGImage), 0, colorSpace, CGImageGetBitmapInfo(image.CGImage));
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillRect(context, CGRectMake(0, 0, fw, fh));
    CGRect rect = CGRectMake(ox, oy, image.size.width, image.size.height);
    CGContextDrawImage(context, rect, image.CGImage);
    CGImageRef newCGImage = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    UIImage *finalImage = [UIImage imageWithCGImage:newCGImage];
    CGImageRelease(newCGImage);
    return finalImage;
}

有人能指出我做错了什么,或者给我一些优化来减少这个实用程序的处理时间?提前谢谢!

1 个答案:

答案 0 :(得分:2)

解决方案

最后,经过对CGGraphicsUIGraphics内容的大量讨论,我发现问题根本不在于实用程序。上面的代码很完美,但罪魁祸首就是我加载UIImage的方式。

我正在使用

[UIImage imageNamed:@"twomb.jpg"];

加载图片。 imageNamed方法将图像缓存在内存中,全部为2MB。那耗费时间。将上述行更改为

[UIImage imageWithContentsOfFile:@"twomb.jpg"];

时间和记忆的使用都大大减少了。