2015-04-22 5 views
6

I CAShapeLayer.path und CALayer.mask bin mit Bildmaske einzurichten, ich kann durch Einstellung von „Differenz-Set“ und „Union“ -Effekt für CGPath erreichenWie bekomme ich die Schnittmenge von zwei CGPath?

maskLayer.fillRule = kCAFillRuleEvenOdd/kCAFillRuleZero 

aber wie kann ich die Kreuzung zweier Wege bekommen? Ich kann es nicht mit Gerade-Ungerade-Regel erreichen

Hier ist ein Beispiel: enter image description here

let view = UIImageView(frame: CGRectMake(0, 0, 400, 400)) 
view.image = UIImage(named: "scene.jpg") 
let maskLayer = CAShapeLayer() 
let maskPath = CGPathCreateMutable()  
CGPathAddEllipseInRect(maskPath, nil, CGRectOffset(CGRectInset(view.bounds, 50, 50), 50, 0)) 
CGPathAddEllipseInRect(maskPath, nil, CGRectOffset(CGRectInset(view.bounds, 50, 50), -50, 0)) 
maskLayer.path = maskPath 
maskLayer.fillRule = kCAFillRuleEvenOdd 
maskLayer.path = maskPath 
view.layer.mask = maskLayer 

, wie kann ich den mittleren Teil davon bekommen gezeigt werden? Ich meine, nur der mittlere Teil (der in der Beispielansicht leer ist).

ich es kann in Vektor-Design-Software wie AI leicht tun, so dass ich denke, es gibt einen Weg zu handhaben sein.

+0

Siehe für eine Technik http://robnapier.net/clipping-cgrect-cgpath. Die gleiche Technik kann für mehrere CGPaths verwendet werden (gilt für alles, was Sie zeichnen können). –

Antwort

7
extension UIImage { 
    func doubleCircleMask(#circleSize:CGFloat)-> UIImage { 
     let rectangle = CGRectMake(0, 0, size.width, size.height) 
     UIGraphicsBeginImageContext(size) 
     let x = size.width/2-circleSize/2 
     let y = size.height/2-circleSize/2 
     let offset = circleSize/4 
     let shape1 = UIBezierPath(roundedRect: CGRectMake(x-offset, y, circleSize, circleSize), cornerRadius: circleSize/2) 
     shape1.appendPath(UIBezierPath(roundedRect: CGRectMake(x+offset, y, circleSize, circleSize), cornerRadius: circleSize/2)) 
     shape1.addClip() 
     drawInRect(rectangle) 
     let result = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return result 
    } 
    func doubleCircleIntersectionMask(#circleSize:CGFloat)-> UIImage { 
     let rectangle = CGRectMake(0, 0, size.width, size.height) 
     UIGraphicsBeginImageContext(size) 
     let x = size.width/2-circleSize/2 
     let y = size.height/2-circleSize/2 
     let offset = circleSize/4 
     let shape1 = UIBezierPath(roundedRect: CGRectMake(x-offset, y, circleSize, circleSize), cornerRadius: circleSize/2) 
     let shape2 = UIBezierPath(roundedRect: CGRectMake(x+offset, y, circleSize, circleSize), cornerRadius: circleSize/2) 
     shape1.addClip() 
     shape2.addClip() 
     drawInRect(rectangle) 
     let result = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return result 
    } 

} 

Testing

let myPicture = UIImage(data: NSData(contentsOfURL: NSURL(string: "http://i.stack.imgur.com/Xs4RX.jpg")!)!)! 

let myPictureUnion = myPicture.doubleCircleMask(circleSize: 300) 

let myPictureIntersection = myPicture.doubleCircleIntersectionMask(circleSize: 300) 

enter image description here

+0

Ja, mit 'UIBezierPath' statt' CGPath' es durch FillRule ermöglichen Multi-Clip, anstatt dass sie beschränkt zu tun. Danke vielmals. – duan

+0

Um klar zu sein, kann dies auch mit 'CGPath's erfolgen, so der Kommentar nur' UIBezierPath's es möglich macht, ist nicht korrekt. Schaut sie einfach mal diesen [Spielplatz] (https://gist.github.com/henrinormak/c6f792ed269723def347) Ich schrieb exakt die gleiche Logik wie in dieser Antwort verwenden, aber mit 'CGContext' und' CGPath' statt –

+0

@HenriNormak cool. – duan

Verwandte Themen