首页 > 解决方案 > CGContext,单独绘制相邻路径时的问题,不要混合在一起

问题描述

这是我在堆栈上的第一篇文章,所以请原谅我不知道的任何礼仪问题

我正在为我的一个应用程序创建一个简单的绘图引擎。它主要基于苹果铅笔的 Apple Touch Canvas 演示 https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/illustrating_the_force_altitude_and_azimuth_properties_of_touch_input

该引擎通过抚摸路径工作,因为我需要平滑地改变宽度我决定通过填充路径来完成,创建该路径的逻辑与这个 cocos2d 项目 https://github.com/krzysztofzablocki/LineDrawing非常相似

目前我对引擎的性能非常满意,因此我决定更加雄心勃勃:根据力引入可变不透明度。为此,我不是从笔划中绘制整个路径,而是将其细分为段,使用笔划线的段看起来像这样

<img src="https://i.stack.imgur.com/xdnQU.png" alt="strokedpath">

我一个一个地绘制每个段路径,在填写的表格中,它看起来像这样 填充路径

所以没有问题吧?好吧,如果您有 Ipad(或缩放),您会注意到一个问题

缝合路径 </p>

这些路径实际上是缝合在一起的!没有平稳过渡。似乎是一个抗锯齿问题。我注意到的是,如果我将一个新片段的开头稍微偏移到前一个片段(现在,前一个片段的结尾是新片段的开头),它似乎融合得更好,有时会消失针迹完全,但这非常棘手,虽然它适用于完全不透明度的颜色,但当您降低不透明度时,相同的常数可能不起作用,有时使用模拟器与真实设备时结果会有所不同

我有点迷路了,有什么办法可以平滑段之间的过渡吗?

这是我的绘图例程,现在我正在使用渐变,但我已经尝试用没有剪裁的纯色填充路径并得到相同的结果

for (index,subpath) in pathResults.subPaths.enumerated(){
        //Si no es inicio de linea el primer segmento es historico para suavizar, no dibujar
        if !startOfLine && index == 0{
            continue
        }
        let colors = [properties.color.cgColor.copy(alpha: opacityForPoint(subpath.startPoint)),
                     properties.color.cgColor.copy(alpha: opacityForPoint(subpath.endPoint))]
            as CFArray
        if let gradient = CGGradient(colorsSpace: context.colorSpace,
                                     colors: colors,
                                     locations: [0.0,1.0]){
            context.addPath(subpath.subpath)
            context.clip()
            context.drawLinearGradient(gradient,
                                       start: subpath.startPoint.properties.location,
                                       end: subpath.endPoint.properties.location,
                                       options: gradientOptions)
            context.resetClip()
        }
    }

这是我绘制的上下文的代码:

private lazy var frozenContext: CGContext = {
    let scale = self.properties.scale
    var size = self.properties.size

    size.width *= scale
    size.height *= scale
    let colorSpace = CGColorSpaceCreateDeviceRGB()

    let context: CGContext = CGContext(data: nil,
                                       width: Int(size.width),
                                       height: Int(size.height),
                                       bitsPerComponent: 8,
                                       bytesPerRow: 0,
                                       space: colorSpace,
                                       bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!

    let transform = CGAffineTransform(scaleX: scale, y: scale)
    context.concatenate(transform)

    return context
}()

标签: swiftdrawingcore-graphicscgcontextcgpath

解决方案


推荐阅读