我正在使用UIImageView显示图像的缩略图,然后可以选择以全尺寸查看。 UIImageView的内容模式设置为宽高比。
图像通常从大约500px x 500px缩小到100px x 100px。在视网膜iPad上,它们显示得非常好,而在iPad2上,它们的颜色非常混乱,直到尺寸接近原始图像尺寸。
示例:
原始图片
Retina iPad渲染速度为100px x 100px
iPad 2渲染速度为100px x 100px
iPad 2和新iPad之间的差异可能只是屏幕分辨率,或者可能是GPU更适合缩放图像。无论哪种方式,iPad 2渲染都很差。
我首先尝试通过创建新上下文来缩小图像大小,将插值质量设置为高并将图像绘制到上下文中。在这种情况下,两张iPad上的图像看起来都很好。
在我继续图像复制/调整大道之前,我想检查一下我没有找到更简单的东西。我很欣赏UIImage不会被缩放,但我的印象是UIImageView可以处理扩展,但目前看起来并没有做好缩小的工作。我错过了什么(如果有的话)?
更新:注意:渲染/调整大小的图像上的阴影会添加到代码中。禁用此功能对缩放的质量没有任何影响。
答案 0 :(得分:73)
我尝试过的另一种方法似乎是改进的方法是设置minificationFilter:
[imageView.layer setMinificationFilter:kCAFilterTrilinear]
质量肯定有所改善,我没有发现性能受到影响。
答案 1 :(得分:7)
如果你只是将大图像放在一个小的图像视图中,它看起来会很糟糕。
解决方案是正确调整图像的大小...我将添加一个示例函数来完成这个技巧:
- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = image.CGImage;
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
CGContextConcatCTM(context, flipVertical);
CGContextDrawImage(context, newRect, imageRef);
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
UIGraphicsEndImageContext();
return newImage;
}
此函数可能需要一些时间..因此您可能希望将结果保存到缓存文件中。
答案 2 :(得分:6)
如果你不怕浪费记忆并知道你为某个特定情况做了什么,那么这种方法很有效。
myView.layer.shouldRasterize = YES;
myView.layer.rasterizationScale = 2;
结果质量比setMinificationFilter好得多。
我正在使用256x256的图像并将它们缩放到类似48像素的像素。显然,这里更安全的解决方案是将图像缩小到精确的目标尺寸。
答案 3 :(得分:5)
如果您不想自己重新取样,那么应用小的缩小滤镜偏差可以解决这个问题:
imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.minificationFilterBias = 0.1
左图没有应用过滤。右图有0.1偏滤。
请注意,不需要显式光栅化。
使用非常小的值,你通常可以提出一个值来平滑缩放工件,这比自己调整位图大小要容易得多。当然,随着偏差的增加,你会丢失细节,所以即使小于0.1的值也可能就足够了,尽管这一切都取决于图像视图显示图像的帧的大小。
只要意识到三线性过滤有效地在图层上启用mipmapping,这基本上意味着它会以逐渐变小的比例生成位图的额外副本。这是一种非常常见的技术,用于渲染以提高渲染速度并减少缩放混叠。权衡是需要更多内存,尽管连续下采样位图的内存使用量呈指数级下降。
这项技术的另一个潜在优势,虽然我自己没有尝试过,但你可以为minificationFilterBias
制作动画。因此,如果您要将图像视图作为动画的一部分进行缩放,请考虑将过滤器偏差从0.0
设置为您确定的适合缩小尺寸的小值。
最后,正如其他人所说,如果您的源图像非常大,如果过度使用此技术则不合适,因为Core Animation将始终保留原始位图。在大多数情况下,最好调整图像大小然后丢弃源图像而不是使用mipmapping,但对于一次性或者图像视图将要足够快地解除分配的情况,这很好。
答案 4 :(得分:1)
接下来帮助了我:
imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.shouldRasterize = true
imageView.layer.rasterizationScale = UIScreen.mainScreen().scale
如果在滚动列表中使用,密切关注效果。