在iPhone应用程序从磁盘加载图像是缓慢的

在我的iPhone应用程序中,我使用iPhone的相机拍摄照片并将其保存到磁盘(应用程序的文档文件夹)中。 这是我如何保存它:

[UIImageJPEGRepresentation(photoTaken, 0.0) writeToFile:jpegPath atomically:YES]; 

使用最大的压缩率,我认为从磁盘读取图像会很快。 但它不是! 我使用该图像作为我的一个视图中的button的背景图像。 我像这样加载它:

 [self.frontButton setBackgroundImage:[UIImage imageWithContentsOfFile:frontPath] forState:UIControlStateNormal]; 

当我用这个button导航到视图时,它很慢且波涛汹涌。 我该如何解决?

+imageWithContentsOfFile:是同步的,所以你的主线程上的UI被磁盘操作加载的图像所阻塞,导致不稳定。 解决scheme是使用从磁盘asynchronous加载文件的方法。 你也可以在后台线程中做到这一点。 这可以通过在dispatch_async()包装+imageWithContentsOfFile:然后在包装-setBackgroundImage:的主队列上嵌套dispatch_async() -setBackgroundImage:因为UIKit方法需要在主线程上运行。 如果您希望在加载视图后立即显示图像,则需要预先从磁盘caching图像,以便在视图出现时立即将其存储在内存中。

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ UIImage *image = [UIImage imageWithContentsOfFile:frontPath]; dispatch_async(dispatch_get_main_queue(), ^{ [self.frontButton setBackgroundImage:image forState:UIControlStateNormal]; }); }); 

另外,如果button图像发生了渐变,请考虑使用以下属性来确保从磁盘加载的图像文件很小:

 - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets 

或者(不推荐使用,仅在需要支持iOS 4.x时使用):

 - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight 

这是我知道的更快的方式。 您需要导入#import <ImageIO/ImageIO.h>

我使用这段代码在滚动过程中下载和压缩图像,在滚动视图中,你几乎没有注意到延迟。

 CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)mutableData, NULL); CFDictionaryRef options = (CFDictionaryRef)[[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent, (id)[NSNumber numberWithDouble:200.0], (id)kCGImageSourceThumbnailMaxPixelSize, nil]; CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); UIImage *image = [[UIImage alloc] initWithCGImage:thumbnail]; // Cache NSString *fileName = @"fileName.jpg"; NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"thumbnail"]; path = [path stringByAppendingPathComponent:fileName]; if ([UIImagePNGRepresentation(image) writeToFile:path atomically:YES]) { // Success }