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) 可以解决问题。