Quartz2D:如何在运行时将剪切矩形转换为倒置蒙版?

Posted

技术标签:

【中文标题】Quartz2D:如何在运行时将剪切矩形转换为倒置蒙版?【英文标题】:Quartz2D: How to convert a clipping rect to an inverted mask at runtime? 【发布时间】:2013-01-03 19:19:39 【问题描述】:

给定:

    一个带有框架0,0,100,100的CGContextRef (ctx) 和一个矩形 (r),带有框架 25,25,50,50

将上下文剪辑到该矩形很容易:

CGContextClipToRect(ctx, r);

遮住下面的红色区域(red == mask)

但我想反转这个剪裁矩形以将其转换为剪裁蒙版。期望的结果是掩盖下面的红色部分(red == mask)

我想在运行时以编程方式执行此操作。

想要手动准备位图图像以与我的应用一起静态发布。

鉴于ctxr,如何在运行时最轻松/直接地做到这一点?

【问题讨论】:

【参考方案1】:

阅读“Filling a Path” section of the Quartz 2D Programming Guide中的填充规则。

在您的情况下,最简单的方法是使用奇偶填充规则。创建一个由你的小矩形和一个更大的矩形组成的路径:

CGContextBeginPath(ctx);
CGContextAddRect(ctx, CGRectMake(25,25,50,50));
CGContextAddRect(ctx, CGRectInfinite);

然后,使用奇偶填充规则将该路径与剪切路径相交:

CGContextEOClip(ctx);

【讨论】:

是的,完美。我知道一定有办法。谢谢罗伯。【参考方案2】:

您可以通过传递构成您想要的红框的矩形来使用CGContextClipToRects() 剪辑上下文。

【讨论】:

是的,恐怕这可能是最简单的解决方案。但我希望有一些我忽略的更优雅/更简单的东西。对于矩形情况,您的建议相当容易。但是给定一条路径,您的解决方案将无法正常工作。这让我觉得 Quartz2D 中一定有更好的解决方案…… 然后您可以使用 CGContextClipToMask() 并在 UIImage 中绘制边框/框架。【参考方案3】:

你能像往常一样做所有的画,然后做:

CGContextClearRect(ctx, r);

一切都完成之后?

【讨论】:

看起来应该可以,但CGContextClearRect() 总是在给定的矩形中“填充黑色”(我从来不理解)。所以,不,我认为这行不通。 CGContextClearRect 将每个像素的所有分量设置为零。如果您的上下文具有 Alpha 通道,则每个像素都会变得清晰。否则,每个像素都会变黑。【参考方案4】:

这是实现 rob 答案的有用扩展

extension UIBezierPath 
    func addClipInverse() 
        let paths = UIBezierPath()
        paths.append(self)
        paths.append(.init(rect: .infinite))
        paths.usesEvenOddFillRule = true
        paths.addClip()
    

【讨论】:

以上是关于Quartz2D:如何在运行时将剪切矩形转换为倒置蒙版?的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发UI篇—Quartz2D使用(图片剪切)

停止相机中的Y轴反转

如何在 Core Graphics / Quartz 2D 中绘制圆角矩形?

ArcGIS如何从矢量图剪切出一个矩形区域出来?

C ++ / OpenGL - 2D - 如何在矩形边界框中剪切圆

如何在Android中剪切矩形内的圆形路径