反别名,UIImage和性能
我有一个UIImage
加载到UIImageView
。 UIImage
比UIImageView
,它已经缩小到适合。 显然缩小的UIImage
显示锯齿状的边缘。
在性能方面反对这个图像的最好方法是什么?
我已经看到了使用drawInRect
这个方法,但是我也读过了drawInRect
并没有给出最好的性能 。
我已经阅读了几篇不同的文章,并且我自己尝试了一些方法。 但在阅读了关于使用UIViews
和Core Graphics之间性能差异的更多 文章之后,我想知道哪种抗锯齿方法能够提供最佳性能?
调查可用的核心图像filter的列表。 具体来说,通过CILanczosScaleTransform
提供的Lanczos Scale Transform似乎正是您所需要的。 它应该可用于所有iOS版本> = 6.0。
通常,使用核心图像filter将比手动诉诸核心graphics更高性能。 不过,我恳请您核实结果以及您的具体情况下的performance。
最好的解决scheme是在你的UIImageView
总是有正确的图像大小。 但是,如果您无法获得正确的图像大小,并且需要resize,另一个好方法是使用CoreGraphics在主线外执行图像缩放操作。
由于SDK 4.0, CoreGraphics操作是线程安全的 ,因此您可以将所有resize的东西放入后台队列中,并处理其中的大小调整。 一旦resize完成后,您必须在主线程中的UIImageView
中分配裁剪的图像,因为所有UIKit
东西都必须在该线程中完成。 采用这种方法,每次调整图像大小时都不会阻塞主线程。
一旦你这样做,你也可以caching裁剪结果,以避免重复裁剪计算(即每次滚动到相同的UITableViewCell
),并提高性能。
你可以实现这个UIImage
类别,以我的代码为例:
- (void)resizeImageWithSize:(CGSize)size cacheKey:(NSString *)cacheKey completionBlock:(void (^)(UIImage *croppedImage))completionBlock { dispatch_async([[self class] sharedBackgroundQueue], ^{ // Check if we have the image cached UIImage *resizedImage = [[[self class] resizedImageCache] objectForKey:cacheKey]; if (nil == resizedImage) { // If not, resize and cache it @autoreleasepool { resizedImage = [self resizeImageWithSize:size]; [[[self class] resizedImageCache] setObject:resizedImage forKey:cacheKey]; } } dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(resizedImage); }); }); }
然后, resizeImageWithSize:
方法的实现是所有CoreGraphics的东西发生的地方。 你可能会发现Nick Lockwood的FXImageView库有趣,它使用了相同的方法: UIImageView
类,有一个resize的caching,并使用后台线程来做Core Graphics的东西。
既然你在评论中询问了Swift,
Alamofire拥有所有这一切,包括一个自动caching层。 如果你不使用networking请求,至less这是一个很好的例子。
例:
// Note: this seamlessly handles both scaling AND caching the scaled image let filter = AspectScaledToFillSizeFilter(size: imageView.frame) imageView.af_setImage(withURL: url, filter: filter)
只要确保imageView.frame事先设置(例如,首先调用layoutIfNeeded()
为自动布局),否则它会断言。