如何获得两个 CGPath 的交集?
How to get the intersection of two CGPath?
我正在使用 CAShapeLayer.path
和 CALayer.mask
设置图像遮罩,我可以通过设置 [=] 实现 CGPath
的 "difference set" 和 "union" 效果16=]
maskLayer.fillRule = kCAFillRuleEvenOdd/kCAFillRuleZero
但是,我怎样才能得到两条路径的交点呢?我用奇偶规则无法实现
这是一个例子:
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
如何显示中间的交叉区域?
extension UIImage {
func doubleCircleMask(diameter: CGFloat)-> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
defer { UIGraphicsEndImageContext() }
let x = size.width/2 - diameter/2
let y = size.height/2 - diameter/2
let offset = diameter/4
let bezierPath: UIBezierPath = .init(ovalIn: .init(origin: .init(x: x-offset, y: y), size: .init(width: diameter, height: diameter)))
bezierPath.append(.init(ovalIn: .init(origin: .init(x: x+offset, y: y), size: .init(width: diameter, height: diameter))))
bezierPath.addClip()
draw(in: .init(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
func doubleCircleIntersectionMask(diameter: CGFloat)-> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
defer { UIGraphicsEndImageContext() }
let x = size.width/2 - diameter/2
let y = size.height/2 - diameter/2
let offset = diameter/4
UIBezierPath(ovalIn: .init(origin: .init(x: x-offset, y: y), size: .init(width: diameter, height: diameter))).addClip()
UIBezierPath(ovalIn: .init(origin: .init(x: x+offset, y: y), size: .init(width: diameter, height: diameter))).addClip()
draw(in: .init(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
测试
let image = UIImage(data: try! Data(contentsOf: URL(string: "http://i.stack.imgur.com/Xs4RX.jpg")!))!
let imageUnion = image.doubleCircleMask(diameter: 300)
let imageIntersection = image.doubleCircleIntersectionMask(diameter: 300)
我正在使用 CAShapeLayer.path
和 CALayer.mask
设置图像遮罩,我可以通过设置 [=] 实现 CGPath
的 "difference set" 和 "union" 效果16=]
maskLayer.fillRule = kCAFillRuleEvenOdd/kCAFillRuleZero
但是,我怎样才能得到两条路径的交点呢?我用奇偶规则无法实现
这是一个例子:
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
如何显示中间的交叉区域?
extension UIImage {
func doubleCircleMask(diameter: CGFloat)-> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
defer { UIGraphicsEndImageContext() }
let x = size.width/2 - diameter/2
let y = size.height/2 - diameter/2
let offset = diameter/4
let bezierPath: UIBezierPath = .init(ovalIn: .init(origin: .init(x: x-offset, y: y), size: .init(width: diameter, height: diameter)))
bezierPath.append(.init(ovalIn: .init(origin: .init(x: x+offset, y: y), size: .init(width: diameter, height: diameter))))
bezierPath.addClip()
draw(in: .init(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
func doubleCircleIntersectionMask(diameter: CGFloat)-> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
defer { UIGraphicsEndImageContext() }
let x = size.width/2 - diameter/2
let y = size.height/2 - diameter/2
let offset = diameter/4
UIBezierPath(ovalIn: .init(origin: .init(x: x-offset, y: y), size: .init(width: diameter, height: diameter))).addClip()
UIBezierPath(ovalIn: .init(origin: .init(x: x+offset, y: y), size: .init(width: diameter, height: diameter))).addClip()
draw(in: .init(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
测试
let image = UIImage(data: try! Data(contentsOf: URL(string: "http://i.stack.imgur.com/Xs4RX.jpg")!))!
let imageUnion = image.doubleCircleMask(diameter: 300)
let imageIntersection = image.doubleCircleIntersectionMask(diameter: 300)