如何使用 AVVideoCompositionCoreAnimationTool 获取自定义 CIFilter 以在 CALayer 上工作以进行导出
How can I get a custom CIFilter to work on a CALayer for export using the AVVideoCompositionCoreAnimationTool
使用依赖于自定义输入参数的自定义 CIFilter
时,一旦将过滤器设置为 CALayer
backgroundFilters,就不会使用这些参数,因此您可以使用 [=17] 将其渲染为视频=] 输入参数不再使用,貌似CALayer新建了一个CIFilter,并没有添加设置的参数。
使用默认选项:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.setValue(10, forKey: "value")
layer.backgroundFilters = [filter]
或:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter", options: ["value": 10])!
layer.backgroundFilters = [filter]
或使用 Apple 在手册中提到的内容:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.name = "myFilter"
layer.backgroundFilters = [filter]
layer.setValue(10, forKeyPath: "backgroundFilters.myFilter.value"
无论什么顺序,什么值,如果自定义过滤器是这样定义的:
class CustomFilter: CIFilter {
override class var supportsSecureCoding: Bool {
return true
}
@objc dynamic var inputImage: CIImage?
@objc dynamic var value: NSNumber?
override public var outputImage: CIImage? {
guard let image = inputImage else {
return nil
}
// return the actual stuff you want done here!
}
}
甚至使用以下方式注册:
class CustomFilterRegister: CIFilterConstructor {
static func register() {
CIFilter.registerName(
"CustomFilter", constructor: CustomFilterRegister(),
classAttributes: [
kCIAttributeFilterCategories: [
kCICategoryVideo,
kCICategoryStillImage,
"CustomFilters"
],
])
}
func filter(withName name: String) -> CIFilter? {
switch name {
case "CustomFilter":
return CustomFilter()
default:
return nil
}
}
}
CALayer 不受 value 参数中设置的影响。
为了 CALayers
与自定义 CIFilter
一起工作,似乎有 2 件重要的事情需要添加。
- 您需要覆盖输入键:
override var inputKeys: [String] {
return [kCIInputImageKey, "value"]
}
- 您需要像这样声明所有使用的参数:
override var attributes: [String : Any] {
return [
kCIAttributeFilterDisplayName: "Custom Filter",
kCIAttributeFilterName: "CustomFilter",
kCIAttributeFilterCategories: [
kCICategoryVideo,
kCICategoryStillImage,
"CustomFilters",
],
kCIInputImageKey: [
kCIAttributeIdentity: 0,
kCIAttributeClass: "CIImage",
kCIAttributeDisplayName: "Image",
kCIAttributeType: kCIAttributeTypeImage
],
#keyPath(value): [
kCIAttributeIdentity: 0,
kCIAttributeClass: "NSNumber",
kCIAttributeDisplayName: "Custom value",
kCIAttributeMin: 0,
kCIAttributeMax: 5,
kCIAttributeSliderMin: 0,
kCIAttributeSliderMax: 5,
kCIAttributeType: kCIAttributeTypeScalar
],
kCIOutputImageKey: [
kCIAttributeClass: "CIImage",
kCIAttributeDisplayName: "Output Image",
kCIAttributeType: kCIAttributeTypeImage
]
]
}
希望我能为你们中的一些人节省大量时间来解决这个问题!
使用依赖于自定义输入参数的自定义 CIFilter
时,一旦将过滤器设置为 CALayer
backgroundFilters,就不会使用这些参数,因此您可以使用 [=17] 将其渲染为视频=] 输入参数不再使用,貌似CALayer新建了一个CIFilter,并没有添加设置的参数。
使用默认选项:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.setValue(10, forKey: "value")
layer.backgroundFilters = [filter]
或:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter", options: ["value": 10])!
layer.backgroundFilters = [filter]
或使用 Apple 在手册中提到的内容:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.name = "myFilter"
layer.backgroundFilters = [filter]
layer.setValue(10, forKeyPath: "backgroundFilters.myFilter.value"
无论什么顺序,什么值,如果自定义过滤器是这样定义的:
class CustomFilter: CIFilter {
override class var supportsSecureCoding: Bool {
return true
}
@objc dynamic var inputImage: CIImage?
@objc dynamic var value: NSNumber?
override public var outputImage: CIImage? {
guard let image = inputImage else {
return nil
}
// return the actual stuff you want done here!
}
}
甚至使用以下方式注册:
class CustomFilterRegister: CIFilterConstructor {
static func register() {
CIFilter.registerName(
"CustomFilter", constructor: CustomFilterRegister(),
classAttributes: [
kCIAttributeFilterCategories: [
kCICategoryVideo,
kCICategoryStillImage,
"CustomFilters"
],
])
}
func filter(withName name: String) -> CIFilter? {
switch name {
case "CustomFilter":
return CustomFilter()
default:
return nil
}
}
}
CALayer 不受 value 参数中设置的影响。
为了 CALayers
与自定义 CIFilter
一起工作,似乎有 2 件重要的事情需要添加。
- 您需要覆盖输入键:
override var inputKeys: [String] { return [kCIInputImageKey, "value"] }
- 您需要像这样声明所有使用的参数:
override var attributes: [String : Any] { return [ kCIAttributeFilterDisplayName: "Custom Filter", kCIAttributeFilterName: "CustomFilter", kCIAttributeFilterCategories: [ kCICategoryVideo, kCICategoryStillImage, "CustomFilters", ], kCIInputImageKey: [ kCIAttributeIdentity: 0, kCIAttributeClass: "CIImage", kCIAttributeDisplayName: "Image", kCIAttributeType: kCIAttributeTypeImage ], #keyPath(value): [ kCIAttributeIdentity: 0, kCIAttributeClass: "NSNumber", kCIAttributeDisplayName: "Custom value", kCIAttributeMin: 0, kCIAttributeMax: 5, kCIAttributeSliderMin: 0, kCIAttributeSliderMax: 5, kCIAttributeType: kCIAttributeTypeScalar ], kCIOutputImageKey: [ kCIAttributeClass: "CIImage", kCIAttributeDisplayName: "Output Image", kCIAttributeType: kCIAttributeTypeImage ] ] }
希望我能为你们中的一些人节省大量时间来解决这个问题!