Union UIBezierPaths 而不是追加路径

问题描述 投票:0回答:4

我有一个应用程序,我在其中获取 UIBezierPath 并通过一系列appendPath:调用将其用作画笔。经过几次操作后,如果画笔形状非常复杂,内存就会耗尽,应用程序就会停止运行。我真正想做的是一个完整的联合,就像 Paint Code 所做的那样,但我找不到任何方法来做到这一点。

我将如何联合两个或多个 UIBezierPaths?

编辑:

这是我想要动态实现的视觉效果。

在 Paint Code 中,您采用两条路径并将它们重叠,如下所示: Overlapping paths in Paint Code

但是我想将它们合并/联合成一个新的单一路径,例如:

Merged paths in Paint Code

请注意,在 Paint Code 的底部面板中,现在有一个单一形状的代码,这就是我希望能够通过可能 1000 个原始路径以编程方式获得的代码。

ios core-graphics uibezierpath
4个回答
4
投票

通过遵循 Core Graphics 的 2 个概念,您可以轻松获得想要的结果:-

i)CGBlendMode ii)OverLap2Layer

混合模式告诉上下文如何将新内容应用到自身。它们决定像素数据如何进行数字混合。

 class UnionUIBezierPaths : UIView {

    var firstBeizerPath:UIImage!
    var secondBeizerPath:UIImage!

    override func draw(_ rect: CGRect) {
        super.draw(rect)

       firstBeizerPath = drawOverLapPath(firstBeizerpath: drawCircle(), secondBeizerPath: polygon())
       secondBeizerPath = drawOverLapPath(firstBeizerpath: polygon(), secondBeizerPath: drawCircle())

        let image = UIImage().overLap2Layer(firstLayer:firstBeizerPath , secondLayer:secondBeizerPath)
    }


    func drawCircle() -> UIBezierPath {
        let path = UIBezierPath(ovalIn: CGRect(x: 40, y: 120, width: 100, height: 100) )
        return path
    }

    func polygon() -> UIBezierPath {
        let beizerPath = UIBezierPath()
        beizerPath.move(to: CGPoint(x: 100, y: 10) )
        beizerPath.addLine(to: CGPoint(x: 200.0, y: 40.0) )
        beizerPath.addLine(to: CGPoint(x: 160, y: 140) )
        beizerPath.addLine(to: CGPoint(x: 40, y: 140) )
        beizerPath.addLine(to: CGPoint(x: 0, y: 40) )
        beizerPath.close()
        return beizerPath
    }

    func drawOverLapPath(firstBeizerpath:UIBezierPath ,secondBeizerPath:UIBezierPath )  -> UIImage {

        UIGraphicsBeginImageContext(self.frame.size)

        let firstpath = firstBeizerpath
        UIColor.white.setFill()
        UIColor.black.setStroke()
        firstpath.stroke()
        firstpath.fill()

        // sourceAtop = 20
        let mode = CGBlendMode(rawValue:20)
        UIGraphicsGetCurrentContext()!.setBlendMode(mode!)


        let secondPath = secondBeizerPath
        UIColor.white.setFill()
        UIColor.white.setStroke()
        secondPath.fill()
        secondPath.stroke()

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }



    func drawImage(image1:UIImage , secondImage:UIImage ) ->UIImage
    {
        UIGraphicsBeginImageContext(self.frame.size)
        image1.draw(in: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height) )
        secondImage.draw(in: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height) )

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }

      }

      //OverLap2Layer
      extension UIImage {
      func overLap2Layer(firstLayer:UIImage , secondLayer:UIImage ) -> UIImage {

                UIGraphicsBeginImageContext(firstLayer.size)
                firstLayer.draw(in: CGRect(x: 0, y: 0, width: firstLayer.size.width, height: firstLayer.size.height) )
                secondLayer.draw(in: CGRect(x: 0, y: 0, width: firstLayer.size.width, height: firstLayer.size.height) )

                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return newImage!
            }
        }

第一条路径:-

第二条路径:-

最终结果:-

参考:- 融入核心显卡创建图像

GitHub 演示


2
投票

终于有解决办法了!!

使用 https://github.com/adamwulf/ClippingBezier 你可以找到相交点。然后您可以沿着小路行走,顺时针左转,反之亦然,以留在外面。然后您可以使用点序列生成新路径。


0
投票

您可以使用 GPCPolygon,它是 GPC

的 Objective-C 包装器

-GPCPolygonSet*) initWithPolygons:(NSMutableArray*)points;

- (GPCPolygonSet*) unionWithPolygonSet:(GPCPolygonSet*)p2;


0
投票

从 iOS 16 开始 CGPath 有 union(_:using:) 方法。

你可以从 UIBezierPath 中获取 CGPath,如果你再次需要 UIBezierPath,你可以使用 CGPath 来初始化它,如下所示:

let newPath: UIBezierPath = ///
let unionPath = existingPath.cgPath.union(newPath.cgPath)
existingPath = UIBezierPath(cgPath: unionPath)
© www.soinside.com 2019 - 2024. All rights reserved.