how*_*d10 36 objective-c uiimageview ipad ios
我正在使用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可以处理扩展,但目前它似乎没有做好缩小的工作.我错过了什么(如果有的话)?
更新:注意:渲染/调整大小的图像上的阴影将添加到代码中.禁用此功能对缩放的质量没有任何影响.
how*_*d10 75
我试过的另一种方法似乎是改进的方法是设置minificationFilter:
[imageView.layer setMinificationFilter:kCAFilterTrilinear]
Run Code Online (Sandbox Code Playgroud)
质量肯定有所改善,我没有注意到性能受到影响.
如果你只是将大图像放在一个小的图像视图中,它看起来真的很糟糕.
解决方案是正确调整图像大小...我将添加一个示例函数来完成这个技巧:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
此函数可能需要一些时间..因此您可能希望将结果保存到缓存文件中.
如果你不害怕浪费记忆并知道你为特定情况做了什么,这种方法很有效.
myView.layer.shouldRasterize = YES;
myView.layer.rasterizationScale = 2;
Run Code Online (Sandbox Code Playgroud)
结果质量比setMinificationFilter好得多.
我正在使用256x256的图像,并将它们缩放到像48像素.显然,这里更安全的解决方案是将图像缩小到精确的目标尺寸.
如果您不想自己重新采样图像,则应用较小的缩小滤镜偏差可以帮助解决此问题:
imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.minificationFilterBias = 0.1
Run Code Online (Sandbox Code Playgroud)
左图没有应用过滤。右图的滤镜偏移为0.1。
请注意,不需要显式栅格化。
在使用很小的值的情况下,通常可以想出一个值,该值足以使缩放伪影足够平滑,并且比自己调整位图的大小容易得多。当然,随着偏差的增加,您会失去细节,因此,即使小于0.1的值也足够了,尽管这完全取决于显示图像的图像视图框架的大小。
只要意识到三线性过滤有效地实现了图层上的mipmapping,这基本上意味着它会以越来越小的比例生成位图的额外副本。这是渲染中使用的非常常见的技术,可以提高渲染速度并减少缩放混叠。折衷方案是需要更多的内存,尽管连续降采样的位图的内存使用量呈指数下降。
尽管我自己还没有尝试过,但是这项技术的另一个潜在优势是您可以设置动画minificationFilterBias。因此,如果要在动画中将图像视图缩小很多,请考虑将过滤器偏差动画化为0.0适合于缩小尺寸的任何较小值。
最后,正如其他人指出的那样,如果您的源图像很大,则过度使用此技术是不合适的,因为Core Animation始终会保留原始位图。在大多数情况下,最好调整图像的大小然后丢弃源图像,而不是使用mipmapping,但是对于一次性操作或图像视图将被足够快地重新分配的情况,这很好。