When using a custom CIFilter
that relies on custom input parameters the parameters are not used once you set the filter to the CALayer
backgroundFilters so you can render it as a video using AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer(s):)
the input parameters are no longer used, it looks like CALayer creates a new CIFilter and does not add the set parameters.
Using the default options:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.setValue(10, forKey: "value")
layer.backgroundFilters = [filter]
or:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter", options: ["value": 10])!
layer.backgroundFilters = [filter]
or using what Apple mentions in the manual:
let layer = CALayer()
let filter = CIFilter(name: "CustomFilter")!
filter.name = "myFilter"
layer.backgroundFilters = [filter]
layer.setValue(10, forKeyPath: "backgroundFilters.myFilter.value"
No matter what order, what values, if the custom filter is defined like this:
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!
}
}
and even registered using:
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
}
}
}
The CALayer is NOT affected by the setting in the value param.
There seem to be 2 things that are important to add in order for CALayers
to work with the custom CIFilter
.
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 ] ] }
Hope I save some of you loads of time figuring this one out!