联盟UIBezierPath而不是追加路径

时间:2014-05-06 14:35:08

标签: ios core-graphics uibezierpath

我有一个应用程序,我在其中使用UIBezierPath并通过一系列appendPath:调用将其用作画笔。经过一些事情,并且具有非常复杂的刷子形状,内存耗尽,应用程序停止运行。我真正想做的就是像Paint Code那样完全结合,但我无法找到任何方法。

我如何组合两个或更多UIBezierPaths?

编辑:

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

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

但我想将它们合并/合并为一个新的单一路径,如:

Merged paths in Paint Code

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

3 个答案:

答案 0 :(得分:2)

通过遵循核心图形的2个概念,您可以轻松获得所需的结果: -

  

ⅰ)CGBlendMode   ⅱ)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!
            }
        }

第一条路径: -

enter image description here

第二条道路: -

enter image description here

最终结果: -

enter image description here

参考的: - Blend in Core GraphicsCreating Image

GitHub Demo

答案 1 :(得分:1)

最后一个解决方案!

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

答案 2 :(得分:0)

您可以使用GPCPolygonGPC

的Objective-C包装器

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

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