Union UIBezierPaths rather than apend path

后端 未结 3 1002
误落风尘
误落风尘 2020-12-03 11:17

I have an app where I take a UIBezierPath and use it as a brush by a series of appendPath: calls. After a few goes and with really complex brush shapes the memory runs out a

相关标签:
3条回答
  • 2020-12-03 11:52

    You can use the GPCPolygon, an Objective-C wrapper for GPC

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

    or

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

    0 讨论(0)
  • 2020-12-03 12:08

    Finally a solution!!

    Using https://github.com/adamwulf/ClippingBezier you can find the intersecting points. Then you can walk through the path, turning left if clockwise or vice-versa to stay on the outside. Then you can generate a new path using the sequence of points.

    0 讨论(0)
  • 2020-12-03 12:10

    You can get desired result easily by following 2 concepts of Core Graphics :-

    i)CGBlendMode ii)OverLap2Layer

    Blend modes tell a context how to apply new content to itself. They determine how pixel data is digitally blended.

     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!
                }
            }
    

    First Path :-

    Second Path :-

    Final Result :-

    Reference:- Blend in Core Graphics , Creating Image

    GitHub Demo

    0 讨论(0)
提交回复
热议问题