CIFilter 不回答自定义过滤器的 kCIAttributeDescription

Posted

技术标签:

【中文标题】CIFilter 不回答自定义过滤器的 kCIAttributeDescription【英文标题】:CIFilter does not answer the kCIAttributeDescription of a custom filter 【发布时间】:2021-10-16 23:00:57 【问题描述】:

我创建了一个自定义 CIFilter 并使用类 func registerName 方法将其注册到 CIFilter 类中。自定义过滤器已创建并按预期工作。 但是 CIFilter 不回答注册的 kCIAttributeDescription。

CIFilter.localizedDescription(forFilterName: ciFilterName) 不回答 registerName 方法中使用的字符串。 如果自定义过滤器实际被实例化,它确实包含属性描述。

系统中的所有 Apple 过滤器都会在不创建过滤器的情况下回答本地化描述。用户获取有关过滤器的信息以帮助选择过滤器。

自定义过滤器如何实现相同的行为?

这是注册码

 CIFilter.registerName(kPRandom, constructor: PGLFilterConstructor(), 
            classAttributes: [
                             kCIAttributeFilterDisplayName : "Random Filters",

                              kCIAttributeFilterCategories :
                                        [ kCICategoryStillImage,
                                        kCICategoryTransition],

                              kCIAttributeDescription : "Swipe on stack Make command to add random filters to the stack. Select photos for random input with Parms Pick command"               
                          ]
        )

p.s 自定义过滤器用于 App Store 上的 iPad“Wills Filter Tool”应用程序。探索过滤器的世界非常棒,因此随机过滤器生成器被证明是应用过滤器的一个很好的学习和实验工具。

p.p.s 演示问题的 Swift Playground

import UIKit
import CoreImage

// demonstrates that registering a custom filter does
// not register the kCIAttributeDescription

let kPRandom = "Random Filters"
let kCIDissolveFilter = "CIDissolveTransition"

class PGLFilterConstructor: CIFilterConstructor 
    //MARK: CIFilterConstructor protocol

    func filter(withName: String) -> CIFilter? 

        return CIFilter(name: withName)

        




class PGLRandomFilterAction: CIFilter 
    // filter that answers the input as the outputImage
    // a pass thru filter

    @objc dynamic   var inputImage: CIImage?

    class func register() 
        CIFilter.registerName(kPRandom, constructor: PGLFilterConstructor(), classAttributes:
                 [
                    kCIAttributeFilterDisplayName : "Random Filters",

                    kCIAttributeFilterCategories :
                        [ kCICategoryStillImage,
                        kCICategoryTransition],

                    kCIAttributeDescription : "Swipe on stack Make command to add random filters to the stack. Select photos for random input with Parms Pick command"
                ]
        )
    

    override var outputImage: CIImage? 
        get 
            return inputImage 
    


PGLRandomFilterAction.register()
    // added to CIFilter

let randomDescription = CIFilter.localizedDescription(forFilterName: kPRandom)
let dissolveDescription = CIFilter.localizedDescription(forFilterName: kCIDissolveFilter)

// randomDescription contains the filter name. Should be the string
// set in the kCIAttributeDescription line
 
// dissolveDescription contains the expected description

【问题讨论】:

我不禁注意到您的 PGLFilterConstructor 不是 Objective-C 内省的。它不是 NSObject 的后代,它的filter(withName:) 没有标记为@objc。会不会是这个问题? 我建议这是***.com/questions/47690745/…的副本 【参考方案1】:

确实,我的 PGLFilterConstructor 不是 NSObject 的后代。但是,将其和 @objc 添加到演示脚本并不能解决问题。

localizedDescription 似乎是自定义注册过滤器的 CIFilter 区域中被忽视的行为。与 CoreImage 中正在进行的所有其他工作相比,这是次要的,所以我认为提交有关该行为的错误报告没有帮助。

所以解决方案是一种变通方法。 该应用程序基于 CIFilter.attributes 使用包装器类自定义 UI 控件。根据过滤器的类型在包装子类中进行自定义。

对于这个问题,在包装子类中添加更多自定义。

在超类包装器(PGLSourceFilter)中返回标准描述

class func localizedDescription(filterName: String) -> String 
    // custom subclasses should override
    guard let standardDescription = CIFilter.localizedDescription(forFilterName: filterName)
        else  return filterName 
    return standardDescription

然后包装子类可以纠正缺失的描述

override class func localizedDescription(filterName: String) -> String 
    // custom subclasses should override
   return "Swipe 'Make' to add random filters. Select photos for random input on Parms 'Pick' command"

【讨论】:

以上是关于CIFilter 不回答自定义过滤器的 kCIAttributeDescription的主要内容,如果未能解决你的问题,请参考以下文章

自定义 Metal CIFilter 中 RGB 通道的值范围是多少?

用于 OS X 应用程序的带有屏蔽 CIFilter 的 NSView

通过自定义 CIFilter 运行图像时 CIImage 属性丢失

在 CALayer 上应用两个以上 CIFilter

应用CIFilter后无论我做什么,图像都变大了

用于合成红色、绿色和蓝色颜色通道的 CIFilter