反别名,UIImage和性能

时间:2015-03-04 09:02:31

标签: ios performance uiimageview uiimage antialiasing

我将UIImage加载到UIImageViewUIImage大于UIImageView,并且已按比例缩小以适应。显然缩小的UIImage显示出锯齿状的边缘。

在效果方面对图像进行反锯齿的最佳方法是什么?

我见过this method using drawInRectI've also read that drawInRect does not give the best performance

我已经阅读了几篇不同的文章,我自己尝试了一些方法。但在阅读few more posts使用UIViews和Core Graphics之间的性能差异后,我想知道哪种抗锯齿方法可以提供最佳性能?< / p>

3 个答案:

答案 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()),否则它将断言。