在多个 CGPath 的内边缘周围绘制辉光
If I create a CGMutablePathRef by adding together two circular paths as shown by the left image, is it possible to obtain a final CGPathRef which represents only the outer border as shown by the right image?
Thanks for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您要求的是贝塞尔路径的并集。 Apple 不提供任何用于计算路径并集的 API。这实际上是一个相当复杂的算法。这里有几个链接:
如果你解释一下你想要什么对于联合路径,我们也许可以提出一些不需要实际计算联合的替代方案。
您可以绘制相当不错的内部发光,而无需实际计算路径的并集。相反,制作一个位图。填充位图上的每个路径。您将使用它作为面具。接下来,创建蒙版的倒置图像,其中填充了联合区域外部的所有内容。您将绘制它以使 CoreGraphics 在联合的内边缘周围绘制阴影。最后,将蒙版设置为您的CGContext蒙版,设置阴影参数,并绘制反转图像。
好吧,这听起来很复杂。但它看起来是这样的(右侧为 Retina 版本):
它并不完美(角落太亮),但相当不错。
这是代码。我传递的是 UIBezierPaths 而不是 CGPaths,但它们之间的转换很简单。我使用一些 UIKit 函数和对象。请记住,您始终可以使用 UIGraphicsPushContext 和 UIGraphicsPopContext 使 UIKit 绘制到任意 CGContext。
首先,我们需要一个掩模图像。它应该是仅 alpha 通道的图像,在任何路径内为 1,在所有路径外为 0。该方法返回这样的图像:
这实际上是困难的部分。现在我们需要一个图像,它是遮罩(路径联合)区域外部各处的发光颜色。我们可以使用 UIKit 函数来使这比纯 CoreGraphics 方法更容易:
使用这两个图像,我们可以将内部发光绘制到路径数组的当前 UIKit 图形上下文中:
为了测试它,我使用几个创建了一个图像圆圈并将其放入 UIImageView 中:
What you are asking for is the union of bezier paths. Apple doesn't ship any APIs for computing the union of paths. It is in fact a rather complicated algorithm. Here are a couple of links:
If you explain what you want to do with the union path, we might be able to suggest some alternatives that don't require actually computing the union.
You can draw a pretty decent inner glow without actually computing the union of the paths. Instead, make a bitmap. Fill each path on the bitmap. You'll use this as the mask. Next, create an inverted image of the mask, that has everything outside of the union area filled. You'll draw this to make CoreGraphics draw a shadow around the inner edge of the union. Finally, set the mask as your CGContext mask, set the shadow parameters, and draw the inverted image.
Ok, that sounds complicated. But here's what it looks like (Retina version on the right):
It's not perfect (too light at the corners), but it's pretty good.
So here's the code. I'm passing around UIBezierPaths instead of CGPaths, but it's trivial to convert between them. I use a some UIKit functions and objects. Remember that you can always make UIKit draw to an arbitrary CGContext using
UIGraphicsPushContext
andUIGraphicsPopContext
.First, we need an mask image. It should be an alpha-channel-only image that is 1 inside any of the paths, and 0 outside all of the paths. This method returns such an image:
That was actually the hard part. Now we need an image that is our glow color everywhere outside of the mask (path union) area. We can use UIKit functions to make this easier than a pure CoreGraphics approach:
With those two images, we can draw an inner glow into the current UIKit graphics context for an array of paths:
To test it, I created an image using a couple of circles and put it in a UIImageView:
Swift 3 中有两种方式:
路径代码:
奇偶填充规则:
clip
Here are two ways in Swift 3:
path code:
even odd fill rule:
clip