在 CALayer 上进行过滤,但形状(不一定是不同的)矩形的并集除外

2024-03-03

我想申请一个CIFilter to a CALayer除了矩形的并集区域之外。 我发布了我不起作用的代码,它的作用恰恰相反,即过滤器仅应用于矩形而不是外部!

func refreshTheFrameWithEffect() {
    self.layer!.masksToBounds = true
    self.layerUsesCoreImageFilters = true
    self.layer!.needsDisplayOnBoundsChange = true

    let filter = CIFilter(name: "CICircleSplashDistortion")
    filter!.setDefaults()
    self.layer!.backgroundFilters = [filter!]

    var excludedRects: [CGRect] = [] //INITIALISE THEM HOW YOU PREFER

    let maskLayer = CAShapeLayer()
    maskLayer.frame = self.bounds
    self.layer!.fillMode = kCAFillRuleEvenOdd
    var maskPath = NSBezierPath()
    for rect in excludedRects {
        maskPath.append(NSBezierPath(rect: rect))
    }

    maskLayer.path = maskPath.CGPath
    self.layer!.mask = maskLayer
    self.layer!.needsDisplay()
}

然后是来自互联网的以下代码,因为 NSBezierPath 没有属性 CGPath,与 UIBezierPath 不同。

public var CGPath: CGPath {
    let path = CGMutablePath()
    var points = [CGPoint](repeating: .zero, count: 3)
    for i in 0 ..< self.elementCount {
        let type = self.element(at: i, associatedPoints: &points)
        switch type {
        case .moveToBezierPathElement: path.move(to: CGPoint(x: points[0].x, y: points[0].y) )
        case .lineToBezierPathElement: path.addLine(to: CGPoint(x: points[0].x, y: points[0].y) )
        case .curveToBezierPathElement: path.addCurve(      to: CGPoint(x: points[2].x, y: points[2].y),
                                                            control1: CGPoint(x: points[0].x, y: points[0].y),
                                                            control2: CGPoint(x: points[1].x, y: points[1].y) )
        case .closePathBezierPathElement: path.closeSubpath()
        }
    }
    return path
}

AFAIK,您不能将图层屏蔽到路径的反面。

一些观察结果:

  1. 如果您只是想删除整个视图内的路径,则可以通过创建由整个视图组成的路径来实现这一点CGRect加上各种内部路径并利用偶数/奇数缠绕/填充规则,但如果您的内部路径彼此重叠,则这将不起作用。

  2. 您可以将图像遮罩到路径的反面(通过创建单独的“图像遮罩”),但这不适用于动态CALayer掩蔽。它用于屏蔽NSImage。因此,如果您同意对视图的筛选部分使用快照,那么这是一个选项。

    有关使用图像蒙版的示例,请参阅下面的代码片段。

  3. 另一种方法是将过滤器应用于整个视图,对其进行快照,将该快照放在相关视图下方,然后将顶级视图屏蔽到内部路径。实际上,将未过滤的视图屏蔽到内部路径,显示其下方视图的过滤快照。

  4. 然而,方法是创建一条代表所有内部路径联合轮廓的路径。如果路径很简单(例如非旋转矩形),这非常简单。如果路径很复杂(一些是旋转的,一些是非矩形路径等),这会变得很棘手。但这个微不足道的场景还不算太糟糕。不管怎样,如果你这样做了,那么你就可以回到那个奇偶技巧了。

我对这些方法都不完全满意,但我没有看到任何其他方法来实现您正在寻找的东西。希望有人能提出一些更好的方法来解决这个问题。


要扩展选项 2(使用通过绘制几条路径(可能重叠)创建的图像蒙版),在 Swift 3 中您可以执行以下操作:

private func maskImageWithPaths(image: NSImage, size: CGSize) -> NSImage {
    // define parameters for two overlapping paths
    
    let center1 = CGPoint(x: size.width * 0.40, y: size.height / 2)
    let radius1 = size.width * 0.20
    
    let center2 = CGPoint(x: size.width * 0.60 , y: size.height / 2)
    let radius2 = size.width * 0.20
    
    // create these two overlapping paths
    
    let path = CGMutablePath()
    path.move(to: center1)
    path.addArc(center: center1, radius: radius1, startAngle: -.pi / 2, endAngle: .pi * 3 / 2, clockwise: false)
    path.move(to: center2)
    path.addArc(center: center2, radius: radius2, startAngle: -.pi / 2, endAngle: .pi * 3 / 2, clockwise: false)
    
    // create image from these paths
    
    let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bitmapFormat: .alphaFirst, bytesPerRow: 4 * Int(size.width), bitsPerPixel: 32)!
    let context = NSGraphicsContext(bitmapImageRep: imageRep)!
    
    context.cgContext.addPath(path)
    context.cgContext.setFillColor(NSColor.blue.cgColor)
    context.cgContext.fillPath()
    let maskImage = context.cgContext.makeImage()!
    
    let mask = CGImage(maskWidth: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: 4 * Int(size.width), provider: maskImage.dataProvider!, decode: nil, shouldInterpolate: true)!
    
    let finalImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)!.masking(mask)!
    return NSImage(cgImage: finalImage, size: size)
}

得出:

这会掩盖绘制的路径。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CALayer 上进行过滤,但形状(不一定是不同的)矩形的并集除外 的相关文章

  • ExpandableLabel iOS 中的“少看”

    我正在使用第三方库可扩展标签 https github com apploft ExpandableLabel实施一个see more特征 我正在寻找仅快速的解决方案 其中包含标签中的文本而不是按钮中的文本 因此这可以完美地工作 添加库并更
  • Swift - 将图像插入 PDF 不再适用于 iOS 13

    目前正在开发在我的贷款计算器应用程序上导出 PDF 的功能 我有一个预览屏幕 可以在您保存 PDF 之前显示它 预览屏幕由带有 html 的 webView 组成 其中包含占位符 我能够成功地将图像插入到正确的占位符上 并将其显示在 PDF
  • 在completionHandlers中存储值 - Swift

    我正在创建一个completionHandler它返回一个字典 但是当我在另一个类中调用这个方法时 它的值是零 func fetchLatestPosts completionHandler responseDict NSDictionar
  • 未捕获的 Kotlin 异常:kotlin.native.In CorrectDereferenceException:非法尝试访问非共享

    我尝试使用 Kotlin MPP Multiplatform 开发 Android 和 iOS 之间的共享库 但我面临着 iOS 中线程的问题 对于我在 iOS 中的应用程序 我在主线程中建立了对象 但它可能调用其他线程中的函数并抛出此异常
  • skView.ignoreSiblingOrder 在 swift 中的重要性/效率?

    这样做有多重要 高效skView ignoreSiblingOrder true初始化场景时 现在 我将其设置为 true 但由于某种原因 当我从 MainMenu 场景启动 GameScene 时 它 会在我的角色之前加载背景 即使背景的
  • 在 Firebase 中构建聊天应用的数据

    我正在关注 Firebase 指南结构化数据 https firebase google com docs database ios structure data flatten data structures对于聊天应用程序 他们建议的结
  • Swift 包管理器:“多个目标名为...”

    我正在尝试构建一个服务器端 Swift Web 应用程序 我的应用程序的基础框架将是Kitura https www kitura io来自IBM 此外 我还想利用AWS SDK Swift https github com noppoMa
  • iOS 11 浮动 TableView 标题

    有一个应用程序包含多个部分 展开 时每个部分有几行 折叠 时没有 每个部分都有一个部分标题 使用以下子类重用它们UITableViewHeaderFooterView等等 到目前为止一切顺利 然后在 iOS 11 中 我使用了可视化调试器
  • CustomNSError 协议有什么作用以及为什么我应该采用它?

    什么是CustomNSError协议的用途以及为什么我应该采用它 Apple提供的文档仅指出 描述错误类型 具体提供域 代码和 用户信息字典 我已经在谷歌上搜索过 但找不到与我的问题相关的任何内容 每种类型都符合Error协议是隐含地桥接的
  • Swift 中的 viewWillLayoutSubviews

    我正在尝试翻译SKScene scene GameScene sceneWithSize skView bounds size 进入 swift 但我收到错误 sceneWithSize 不可用 使用对象构造 SKScene size 我在
  • 来自索引范围 Swift 的新数组

    我怎样才能做这样的事情 从数组中取出前 n 个元素 newNumbers numbers 0 n 目前出现以下错误 error could not find an overload for subscript that accepts th
  • 如何使用 Swift 将“完成”按钮添加到 iOS 中的数字键盘?

    它在默认键盘上工作得很好 但我无法让它在数字键盘上工作 有任何想法吗 据我所知 你不能在键盘部分添加 完成 按钮 你应该添加一个inputAccessoryView to the UITextField or UITextView 如果这就
  • 检查 Swift 中关联类型是否符合协议

    在类似情况下 如何检查对象是否符合 可表示 协议 protocol Representable associatedtype RepresentType var representType RepresentType get set cla
  • 如何在 swiftUI (macOS) 中检测按键按下和释放

    除了标题之外没什么可说的 我希望能够在按下按键和释放按键时 在 macOS 上 在 swiftUI 视图中执行操作 在 swiftUI 中是否有任何好的方法可以做到这一点 如果没有 有什么解决方法吗 不幸的是 键盘事件处理是其中一个令人痛苦
  • 我们能否检测用户是否通过主页按钮或锁定按钮离开而没有监听 darwin 通知?

    我最近向应用程序商店提交了一个新的二进制文件并将其发送以供审核 但它立即被拒绝并显示以下消息 不支持的操作 不允许应用程序监听设备锁定通知 经过一番挖掘后 我发现我们无法使用 com apple springboard lockstate
  • 调用 SwiftUI 中位置 #11、#12 处的额外参数 [重复]

    这个问题在这里已经有答案了 我在 SwiftUI 中的切换开关上不断收到 调用中位置 11 12 处有额外参数 错误 我见过其他人有 调用中的额外参数 错误 但答案似乎没有帮助 另外 我的错误是 位置 11 12 我还没有看到其他人发生这种
  • 对成员“buildBlock()”的引用不明确

    我一直在尝试使用 Swift UI 为 iOS 13 制作一个应用程序 但我不断收到这个奇怪的错误 对成员 buildBlock 的引用不明确 无论我做什么 错误都不会消失 我尝试一次对代码段进行注释 以查看哪一部分可能导致了问题 但唯一有
  • Swift 中的柯里函数

    我想创建一个返回柯里函数的函数 如下所示 func addTwoNumbers a Int b Int gt Int return a b addTwoNumbers 4 b 6 Result 10 var add4 addTwoNumbe
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • ios - Gamekit 的 GKOctree 未找到元素

    我正在尝试使用GKOctree https developer apple com documentation gameplaykit gkoctree用于高效检索 3D 空间中的对象 然而 以下代码似乎没有按预期工作 import Gam

随机推荐