在ios开发过程中,经常会要在界面上显示相册里的图片。而现在的手机像素这么高,在切换页面时加载高质量大图片时,尤其是加载多张图片的情况下,界面会出现可以感觉到的卡顿。
而要解决这种性能问题时就需要一些特殊处理。一种策略是尽量用缩略图代替原图,在需要的时候再加载原图。 再就是减少图片的加载量, 最好一次只加载一张。 就拿翻页设计来说,图片只有到翻新的一页后才真正加载图片,提高效率。
另外一种策略就是用多线程的方式让图片展示不会影响到主线程的响应。但是多线程加载就会遇到UIImage对图片加载的特殊处理问题。在后台线程中用UIImage加载图片时,其实并不是在真正的加载图片,它只是引用到原始的图片数据块,并不会对图片进行解码然后加载,只有到图片真正要展示的时候。 而界面的展示刷新都是由主线程负责的。 这意味着图片真正影响性能的解码工作又回到了主线程了。 这样加后台线程就没有达到我们预期的效果。 这个时候可能需要用到一些trick的办法强制后台线程进行数据解码工作。
Decode trick: (UIImage 的初始化接口基本上
, 都有这个问题。 [UIImage imageNamed:]
[UIImage imageWithData:]
)
// data就是image的数据块。 NSData
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef newImage = CGImageCreateWithPNGDataProvider(dataProvider,
NULL, NO,
kCGRenderingIntentDefault);
//
// force DECODE
const int width = CGImageGetWidth(newImage);
const int height = CGImageGetHeight(newImage);
const CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
const CGContextRef context = CGBitmapContextCreate(
NULL,
width, height,
8, width * 4,
colorspace, kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), newImage);
CGImageRef drawnImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorspace);
//
//这里是处理好的UIImage. 注意把它更新到UIImageView时要切换到主线程。 因为UIImageView不是线程安全的。 对界面的更新都要到主线程进行。
//self.studentImage.image = [UIImage imageWithCGImage:drawnImage];
//
CGDataProviderRelease(dataProvider);
CGImageRelease(newImage);
CGImageRelease(drawnImage);