我将UIImage
加载到UIImageView
。 UIImage
大于UIImageView
,并且已按比例缩小以适应。显然缩小的UIImage
显示出锯齿状的边缘。
在效果方面对图像进行反锯齿的最佳方法是什么?
我见过this method using drawInRect
但I've also read that drawInRect
does not give the best performance。
我已经阅读了几篇不同的文章,我自己尝试了一些方法。但在阅读few more posts使用UIViews
和Core Graphics之间的性能差异后,我想知道哪种抗锯齿方法可以提供最佳性能?< / p>
答案 0 :(得分:3)
调查可用的Core Image Filters列表。具体来说,通过CILanczosScaleTransform
提供的Lanczos比例变换似乎正是您所需要的。它应该适用于所有iOS版本&gt; = 6.0。
通常,使用Core Image过滤器比手动使用Core Graphics更具性能。但是,我建议您验证结果以及特定情况下的性能。
答案 1 :(得分:2)
最佳解决方案始终是UIImageView
中的图片尺寸正确。但是,如果您无法获得正确的图像大小并且需要调整大小,另一个好的解决方案是使用CoreGraphics在主线程之外执行图像缩放操作。
自SDK 4.0 CoreGraphics operations are thread safe以来,您可以将所有调整大小的内容放入后台队列并处理调整大小。调整大小完成后,您必须在主线程中的UIImageView
中分配裁剪后的图像,因为必须在该线程中完成所有UIKit
内容。使用这种方法,每次调整图像大小时都不会阻塞主线程。
完成后,您还可以缓存裁剪结果,以避免重复裁剪计算(即每次滚动到同一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
类别,具有调整大小缓存并使用后台线程来执行Core Graphics的工作。
答案 2 :(得分:1)
因为你在评论中询问了Swift:
Alamofire内置了所有内容,包括自动缓存层。如果你没有将它用于网络请求,至少它是一个很好的例子。
示例:
// 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()
),否则它将断言。