我须要制作一个疾速更新 UIImage 的性能,一开始应用 UIImageView 来显示图片,所以须要频繁的调用 UIImageView.image = newImage
办法来更新图片。代码看起来像这样。
func onSomethingChanged() {myUIImageView.image = newImage}
这样更新图片十分的卡顿,操作和画面响应有肯定的滞后,体验不好,因而思考本人做一个 UIView 来绘制图片,看看是否能够解决。
于是本人自定义了一个 View,继承 UIView 来做,在 draw(rect:)
办法外面做文章。
首先当然是简略粗犷间接 UIImage.draw(in: bounds)
先看看成果。
var image: UIImage? {
didSet {setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {guard let ctx = UIGraphicsGetCurrentContext() else {return}
ctx.addRect(bounds)
ctx.setFillColor(UIColor.black.cgColor)
ctx.fillPath()
if var im = image {im.draw(in: bounds)
}
}
很好,更新速度很快,是现实的成果,不过目前画面是拉伸的,同时还有锯齿。
下图中右边是现实的显示成果,左边则是理论的显示成果,能够看到显著的锯齿。
通过我一番搜寻尝试了以下配置,均无任何帮忙:
ctx.setShouldAntialias(true)
ctx.setAllowsAntialiasing(true)
ctx.interpolationQuality = .high
layer.allowsEdgeAntialiasing = true
layer.minificationFilter = .trilinear
我回忆起之前用 CGImageContext 缩放图片的时候也没有这个问题啊,难道是因为 UIView 自带的这个 CGContext 无奈很好的缩放图片?
于是我想到一个计划:先用一个 CGImageContext 把图片画下来,再弄出一个 CGImage 来,再把这个 CGImage 放到 UIView 的 CGContext 上是否能够呢?
override func draw(_ rect: CGRect) {guard let ctx = UIGraphicsGetCurrentContext() else {return}
ctx.addRect(bounds)
ctx.setFillColor(UIColor.black.cgColor)
ctx.fillPath()
if var im = image {
// 计算出在以后 view 的 bounds 内,放弃图片比例最大的 size
let size = Math.getMaxSizeWithAspect(size: CGSize(width: bounds.width, height: bounds.height), radioWidthToHeight: im.size.width / im.size.height)
// 再换算成 pixel size
let pixelSize = CGSize(width: size.width * layer.contentsScale, height: size.height * layer.contentsScale)
// 创立一个和 pixel size 一样大的 ImageContext
UIGraphicsBeginImageContextWithOptions(pixelSize, true, 1)
guard let imgCtx = UIGraphicsGetCurrentContext() else { return}
// 把 UIImage 画到这个 ImageContext 上
im.draw(in: CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height))
// 再把 cgImg 搞进去
guard let cgImg = imgCtx.makeImage() else { return}
// 图片间接绘制的话,会上下翻转,因而先翻转一下
ctx.scaleBy(x: 1, y: -1)
ctx.translateBy(x: 0, y: -bounds.height)
// 再把 cgImg 画到 UIView 的 Context 上,功败垂成
ctx.draw(cgImg, in: CGRect(x: (bounds.width - size.width) / 2, y: (bounds.height - size.height) / 2, width: size.width, height: size.height))
}
}
问题就此失去解决。
其实我的自身需要是能疾速的更新 image,因为是在做一块相似前期调照片的软件,有很多滑块,拖动后通过 CIFilter 批改照片,所以须要始终更新图像,如果有更好的办法,无妨通知我一下:D
如果以上内容对你有所帮忙,请在这些平台上关注我吧,谢谢:P