前言:在iPhone应用中, 会用到大量图片展示内容, 然而图片处理不当会大幅度影响应用的性能和整体的流畅性, 本文主要针对UIKit中UIImageView控件进行性能优化
开发时, 可以用模拟器来测试图片性能。开启检测后, 红色为耗性能, 需要过多的内存、CPU或者GPU来处理UIKit的控件。
-
Color Blended Layers
: 检测图层颜色图层混合(半透明以及图像重绘) -
Color Copied Images
: 检测由Core Animation生成的寄宿图片(复制图片, 实际开发中极少出现) -
Color Misaligned Images
: 检测图片大小与显示的控件是否相符, 控件使图片缩放和拉伸(不正常的缩放) -
Color Offscreen-Rendered Yellow
: 检测离屏渲染, 应用把图片在屏幕外做处理, 然后把处理后的结果存到内存中, 等需要用到的时候再取出使用, 相对于普通渲染更占用资源.
首先在控制器中用xib创建一个UIImageView, 用于测试图片性能.
约束:
优化前代码:
class ViewController: UIViewController {
@IBOutlet weak var iconImgV: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
iconImgV.image = UIImage(named:"icon")
}
}
**优化前: ** 开启Color Blended Layers
, 可以发现图片外围绿色,图片为红色, 红色代表缩放或者拉伸.
优化后: 可以发现已经没有红色区域.
核心代码:
/// 获取性能优化后的图片
///
/// - Parameters:
/// - image: 需要处理的图片
/// - size: 图片显示的大小
/// - hasBorder: 是否显示边框(默认false)
/// - borderColor: 边框颜色(默认black)
/// - borderWidth: 边框宽度(默认1.0)
/// - isCircular: 是否为圆形(默认false)
/// - backgroundColor: 图片背景色(默认white)
/// - Returns: 优化后的图片
func optimizeImage(With image: UIImage?, size: CGSize, hasBorder: Bool = false, borderColor: UIColor = UIColor.black, borderWidth: CGFloat = 1.0, isCircular: Bool = false,backgroundColor: UIColor? = UIColor.white) -> UIImage? {
guard let image = image else {
return nil
}
// 绘制区域
let rect = CGRect(origin: CGPoint(), size: size)
// 开启core Graphic绘制, 在内存中开辟一个空间用于处理图片,获取图片Context
// - size: 图片大小
// - opaque: 图片是否不透明
// - scale: 图片倍数, 设置0会根据设备自动调整@2x或者@3x
UIGraphicsBeginImageContextWithOptions(size, true, 0)
// 设置背景色填充, 图片圆角化后默认背景色为黑色
backgroundColor?.setFill()
UIRectFill(rect)
// 创建贝塞尔路线, 用于圆角和边框
let path = UIBezierPath(ovalIn: rect)
if isCircular {
// 绘制圆形
if isCircular {
path.addClip()
}
}
// 图片在制定区域内绘制
image.draw(in: rect)
// 绘制边框
if hasBorder {
borderColor.setStroke()
path.lineWidth = borderWidth
path.stroke()
}
// 获取绘制后的图片
let optimizeImage = UIGraphicsGetImageFromCurrentImageContext()
// 关闭core Graphic绘制
UIGraphicsEndImageContext()
return optimizeImage
}