关于iOS开发中的图片显示问题,你可以注意一下,当你在点击页面之间的跳转的时候,会有一些延迟或者卡顿,那么,当页面上需要加载的图片过多或者图片过大的时候,是不是特别明显。这个延迟来自于将图片从文件解压缩渲染到屏幕上这一过程;


在开发中我们用的最多的图片格式就是PNG和JPEG两种格式,那么我们先来了解一下这两种格式分别有什么优缺点:

1、png格式的图片有alpha通道,jpeg则没有;

2、png无损压缩,jpeg则允许你选择0-100%的压缩质量;

3、如果需要alpha通道(透明)那么你就可以使用png的,如果你不需要一个完美的图片信息,那么你就可以使用jpeg格式的,他会忽略那些你看不到的信息,对于大部分的图片可以使用60-70%的压缩质量而不对图片造成明显的影响;


显示一张图片都屏幕上的速度有以下因素:

1、解压缩的时间;

2、从磁盘上alloc/init/ UIImage的时间;

3、将解压缩后的比特转换成CGContent的时间;



优化过的png格式仅仅对大尺寸图片的文件大小有少量减少,100%压缩质量的jpeg图片文件比优化过的png要小,但是100%的质量是失去了压缩的目的。


那么优化方式就是:

1、对于全屏尺寸的图片我们可以在Catalog中绘制cataLog页的一个简单解决方法就是使用CATiledLayer,并禁用fading。这样就可以在后台线程处理图片的显示而不影响scroll的性能,当然快速向右滑动(scroll),相应页的显示就会有一个明显的延迟。这种解决方法的缺点就是很难将横竖屏切换做的很流畅。

2、强制解压缩图片。当第一次使用图片时,iOS会解压它,通常这个解压缩后的版本将滞留一段时间(内存允许)。尽管这么做没什么意义,但你可以通过将图片渲染成一个新的图片来解压缩这个图片,这样你将在一小段时间内获得两个解压缩的版本。


//这一段代码会解压缩这个image,也许他只有1个像素
- (void)decompressImage:(UIImage *)image {
    UIGraphicsBeginImageContext(CGSizeMake(1, 1));
    [image drawAtPoint:CGPointZero];
    UIGraphicsEndImageContext();
}

但是如果UIImage只是通过initWithContentsOfFile创建的,我就不能始终保持这个解压缩的版本。所以我只能使用ImageIO fra framework(iOS4之后可用)中提供的一个选项来显式保持这个解压缩的版本。



NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:(id)kCGImageSourceShouldCache];

CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)dict);
UIImage *retImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
CFRelease(source);



这样初始化图片就可以让解压缩仅发生一次:第一次解压缩消耗很长一段时间,第二次完全不消耗。这其中的关键就是kCGImageSourceShouldCache,你可以为CGImageSource和CGImageSourceCreateImageAtIndex使用这个选项,头文件中是这样说明的:

Specifies whether the image should be cached in a decoded form. The value of this key must be a CFBooleanRef; the default value is kCFBooleanFalse.




如果这个选项设置为NO,绘制图片的时间又会随着解压缩时间增长,如果设置为YES就仅仅解压缩一次。




那么最后我们就知道了:

如果你必须要是有PNG格式的图片且需要alpha通道,推荐你在web服务器上安装pngcrush并处理好所有的png图片,其他情况下,高质量的jpeg图片能更快的解压缩和渲染;