iOS 大图显示
2019-01-16 本文已影响45人
婉卿容若
问题
对于超高分辨率的图片读取存在内存暴涨甚至崩溃的问题, 特别是对于 tableView 中多张图片同时读取的场景.
原因
这里有几篇分析文章
WWDC2018-图像最佳实践 Image and Graphics Best Practices
iOS中的图片使用方式、内存对比和最佳实践
iOS 深入分析大图显示问题
其中第一篇来自 WWDC2018, 它给出了我们最佳的大图显示方式
我们可以从中得到内存暴涨是因为 图片显示前的 decode 操作.
实践
这里来自 WWDC 的代码:
func downsample(imageAt imageURL: URL, to pointSize: CGSize, scale: CGFloat) -> UIImage {
let sourceOpt = [kCGImageSourceShouldCache : false] as CFDictionary
let source = CGImageSourceCreateWithURL(imageURL as CFURL, sourceOpt)!
let maxDimension = max(pointSize.width, pointSize.height) * scale
let downsampleOpt = [kCGImageSourceCreateThumbnailFromImageAlways : true,
kCGImageSourceShouldCacheImmediately : true ,
kCGImageSourceCreateThumbnailWithTransform : true,
kCGImageSourceThumbnailMaxPixelSize : maxDimension] as CFDictionary
let downsampleImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOpt)!
return UIImage(cgImage: downsampleImage)
}
此处需注意两个选项的设置:
1.kCGImageSourceShouldCache此处设为false,目的在于告知系统此imageSource仅为建立与imageURL的链接,不需要解码。
2.kCGImageSourceShouldCacheImmediately设为true,以此控制系统以计算出的size创建Image Buffer并解压。
为了解决 decode 导致的内存暴涨问题, 在 decode 前创建缩略图,对图片进行预处理(缩小解码后 imageBuffer 的 size),从而降低内存占用.
具体分析可以参见 WWDC2018-图像最佳实践 Image and Graphics Best Practices
使用
let url = URL(string: "https://img.haomeiwen.com/i565029/013002ee76523276.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240")
let image = downsample(imageAt: url!, to: CGSize(width:564, height:564), scale: 1.0)
imageView.image = image
这里值得说明的是, downsample(:)
中 imageURL 参数可以是网络/本地 URL
至于在列表中的使用方式 WWDC2018-图像最佳实践 Image and Graphics Best Practices
一文中也有介绍