我有一个使用UIImage
个对象的应用。到目前为止,我一直在使用这样的东西初始化图像对象:
UIImage *image = [UIImage imageNamed:imageName];
在我的应用包中使用图片。我一直在添加功能,允许用户使用UIImagePickerController
从相机或其库中使用图像。显然,这些图片不能出现在我的应用包中,因此我以不同的方式初始化UIImage
对象:
UIImage *image = [UIImage imageWithContentsOfFile:pathToFile];
这是在首次使用Jpeg格式将图像调整为与我的应用程序包中的其他文件大小相似的尺寸(使用Jpeg格式)之后完成的(有趣的是,PNG速度要慢得多,即使对于相同的文件大小也是如此)。换句话说,pathToFile
指向的文件是一个与包中的图像大小相似的文件(像素尺寸匹配,选择了压缩,因此字节数相似)。
该应用程序通过循环从原始图像中制作小块,以及与此帖子无关的其他内容。我的问题是,使用第二种方式创建的图像比使用第一种方式创建的图像需要更长的时间。
我意识到第一种方法缓存图像,但我不认为这是相关的,除非我不理解缓存是如何工作的。如果是相关因素,我该如何向第二种方法添加缓存?
造成瓶颈的相关代码部分是:
[image drawInRect:self.imageSquare];
这里,self是UIImageView的子类。它的属性imageSquare只是一个CGRect
,用于定义绘制的内容。这两部分方法的部分相同。那么为什么第二种方法使用类似大小的UIImage
对象来慢得多?
我是否可以采用不同的方式来优化此过程?
编辑:我将对包中图像的访问权限更改为imageWithContentsOfFile
,并且执行循环的时间从大约4秒更改为超过一分钟。所以看起来我需要找到一些像imageNamed
这样的缓存方法,但是使用非捆绑文件。
答案 0 :(得分:1)
UIImage imageNamed
不会简单地缓存图像。它缓存未压缩的图像。花费的额外时间不是从本地存储器读取到RAM而是通过解压缩图像引起的。
解决方案是创建一个新的未压缩UIImage
对象,并将其用于代码的时间敏感部分。当该段代码完成时,将丢弃未压缩的对象。为了完整性,这里有一个类方法的副本,用于从压缩的对象返回未压缩的UIImage
对象,这要归功于another thread。请注意,这假设数据位于CGImage
。 UIImage
个对象并非总是如此。
+(UIImage *)decompressedImage:(UIImage *)compressedImage
{
CGImageRef originalImage = compressedImage.CGImage;
CFDataRef imageData = CGDataProviderCopyData(
CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
CGImageGetBitsPerComponent(originalImage),
CGImageGetBitsPerPixel(originalImage),
CGImageGetBytesPerRow(originalImage),
CGImageGetColorSpace(originalImage),
CGImageGetBitmapInfo(originalImage),
imageDataProvider,
CGImageGetDecode(originalImage),
CGImageGetShouldInterpolate(originalImage),
CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);
UIImage *decompressedImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
return decompressedImage;
}