iOS 重复调用 CGContext.save/restoreGState(又名 CGContextSave/RestoreGState)导致锯齿
iOS Repeated calling of CGContext.save/restoreGState (aka CGContextSave/RestoreGState) resulting in jaggies
经过多次实验,我发现在重复调用 saveGState()
和 restoreGState
后在上下文中绘制图像会导致锯齿。
这是我在 iOS 8、9 和 10 中观察到的。所以我认为它与任何一个 iOS 版本无关。
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
let ctx = UIGraphicsGetCurrentContext()
for i in 0 ... count {
ctx?.saveGState()
// Some clipping done
image.draw(in: self.bounds)
values.append(animImage)
ctx?.restoreGState()
}
UIGraphicsEndImageContext()
上面的代码是我所做的简化版本。
我实际上需要循环 count
次来剪辑 image
的各个部分,并发现锯齿。
打2、3次好像还可以--也许吧。我没有进行并排比较——但大约 10 次,它肯定会发生。
图片如下:
我可以通过将 UIGraphicsBeginImageContextWithOptions
移动到循环中来解决问题,但我不太确定性能。
质量下降是一个预期的问题还是一个微妙的错误?
此外,与调用 save/restoreGState()
?
相比,如果有的话,为每次迭代开始一个新的上下文对性能有什么影响?
(我只是问,因为我可能没有足够的时间来测试,但没关系)
重新绘制之前,您需要删除之前的图形。看起来您是在旧图层上添加新图层,这使得抗锯齿看起来锐利且参差不齐,因为边缘像素的不透明度每次都会增加。
这就是 UIGraphicsBeginContextWithOptions 为您所做的,正如您在评论中所述,它每次都会为您提供一个全新的状态。
因此,正如您所发现的,添加 ctx?.clear(self.bounds)
可以解决问题。
经过多次实验,我发现在重复调用 saveGState()
和 restoreGState
后在上下文中绘制图像会导致锯齿。
这是我在 iOS 8、9 和 10 中观察到的。所以我认为它与任何一个 iOS 版本无关。
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
let ctx = UIGraphicsGetCurrentContext()
for i in 0 ... count {
ctx?.saveGState()
// Some clipping done
image.draw(in: self.bounds)
values.append(animImage)
ctx?.restoreGState()
}
UIGraphicsEndImageContext()
上面的代码是我所做的简化版本。
我实际上需要循环 count
次来剪辑 image
的各个部分,并发现锯齿。
打2、3次好像还可以--也许吧。我没有进行并排比较——但大约 10 次,它肯定会发生。
图片如下:
我可以通过将 UIGraphicsBeginImageContextWithOptions
移动到循环中来解决问题,但我不太确定性能。
质量下降是一个预期的问题还是一个微妙的错误?
此外,与调用 save/restoreGState()
?
(我只是问,因为我可能没有足够的时间来测试,但没关系)
重新绘制之前,您需要删除之前的图形。看起来您是在旧图层上添加新图层,这使得抗锯齿看起来锐利且参差不齐,因为边缘像素的不透明度每次都会增加。
这就是 UIGraphicsBeginContextWithOptions 为您所做的,正如您在评论中所述,它每次都会为您提供一个全新的状态。
因此,正如您所发现的,添加 ctx?.clear(self.bounds)
可以解决问题。