反别名,UIImage和性能

我有一个UIImage加载到UIImageViewUIImageUIImageView ,它已经缩小到适合。 显然缩小的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()为自动布局),否则它会断言。