8
在我的应用程序中,我需要加载较大的JPEG图像并将它们显示在滚动视图中。为了保持UI的响应,我决定在后台加载图像,然后将它们显示在主线程中。为了在后台完全加载它们,我强制每个图像进行解压缩。我使用此代码来解压缩的图像为(请注意,我的应用程序是仅适用于iOS 7,所以我的理解是用在后台线程这些方法是OK):为什么这段代码比简单的方法更好地解压UIImage?
+ (UIImage *)decompressedImageFromImage:(UIImage *)image {
UIGraphicsBeginImageContextWithOptions(image.size, YES, 0);
[image drawAtPoint:CGPointZero];
UIImage *decompressedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return decompressedImage;
}
然而,我仍然有很长的负载时间,UI口吃和很多内存压力。我刚刚发现another solution:
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
CGImageRef imageRef = image.CGImage;
// System only supports RGB, set explicitly and prevent context error
// if the downloaded image is not the supported format
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef),
8,
// width * 4 will be enough because are in ARGB format, don't read from the image
CGImageGetWidth(imageRef) * 4,
colorSpace,
// kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
// makes system don't need to do extra conversion when displayed.
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
CGColorSpaceRelease(colorSpace);
if (! context) {
return nil;
}
CGRect rect = (CGRect){CGPointZero, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)};
CGContextDrawImage(context, rect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef];
CGImageRelease(decompressedImageRef);
return decompressedImage;
}
该代码的大小更好的订单。图像几乎立即加载,没有UI口吃,并且内存使用已经下降。
所以我的问题是双重的:
- 为什么第二种方法比第好多了?
- 如果第二种方法由于设备的独特参数而更好,是否有办法确保它可以同样适用于所有iOS设备,现在和将来?我不想假设一个本地位图格式在我身上发生变化,重新引入此问题。
辉煌。是的,我在视网膜设备上运行,是的,设置scale = 1给我类似的性能和内存使用。现在我将采用第一种方法,因为无论设备的特性如何,我都希望它能做正确的事情。 –
为了获得两全其美(速度和美感,代价更高的代码),您可能需要显示一个快速的1x渲染(甚至是0.5x渲染),然后返回并在稍后填写视网膜渲染。图像仍然在屏幕上。有关示例,请参阅https://github.com/iosptl/ios6ptl/tree/master/ch13/JuliaOp(这是来自iOS 6编程推动限制的第13章;它将成为iOS 7 PTL中的第9章) ) –
将UIGraphicsBeginImageContextWithOptions更改为scale = 1时,缩放时会使图像渲染质量很差。使用CGImage的代码以高质量渲染,就像不使用强制解压缩一样。 此外,UIGraphicsBeginImageContextWithOptions指定为不透明,不适用于透明度 –