2015-04-22 16 views
6

Używam CAShapeLayer.path i CALayer.mask założyć maskę obrazu, mogę osiągnąć „zestaw różnicy” i „Union” efekt dla CGPath ustawiającJak uzyskać przecięcie dwóch CGPath?

maskLayer.fillRule = kCAFillRuleEvenOdd/kCAFillRuleZero 

jednak, w jaki sposób można uzyskać punkt przecięcia dwóch ścieżek? Nie mogę go osiągnąć z parzystej nieparzystej reguły

Oto przykład: 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 

jak mogę dostać środkową część, aby pokazać? Mam na myśli tylko środkową część (która jest pusta w widoku próbki).

Mogę to zrobić z łatwością w oprogramowaniu do projektowania wektorowego, takim jak sztuczna inteligencja, więc myślę, że musi istnieć sposób na obsłużenie.

+0

Zobacz http://robnapier.net/clipping-cgrect-cgpath dla techniki. Ta sama technika może być użyta dla wielu CGPathów (w rzeczywistości odnosi się do wszystkiego, co możesz narysować). –

Odpowiedz

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 
    } 

} 

Testowanie

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

Tak, użycie 'UIBezierPath' zamiast' CGPath' umożliwia tworzenie wielu klipów zamiast ograniczania przez fillRule. Wielkie dzięki. – duan

+0

Aby było jasne, można to również zrobić za pomocą 'CGPath's, więc komentarz na temat tylko' UibezierPath's to możliwe nie jest dokładne. Po prostu sprawdź to [Playground] (https://gist.github.com/henrinormak/c6f792ed269723def347) Napisałem używając tej samej dokładnej logiki co w tej odpowiedzi, ale używając 'CGContext' i' CGPath' zamiast –

+0

@HenriNormak cool. – duan

Powiązane problemy