我正在尝试创建自定义CIFilter。到目前为止,该滤镜只是使图像变亮,而不是我真正想要的,但是我正在做以查看是否可以使它工作。尽管过滤器可以使用inputBlurRadius的设置值,但我不知道如何更改它,以便用户可以更改该值。这是自定义过滤器。
import Foundation
import UIKit
public class CustomFilter: CIFilter {
var inputImage: CIImage?
private var kernel: CIColorKernel!
var inputBrightness: CGFloat = 0.4
override public var outputImage: CIImage!
{
guard let inputImage = inputImage
else
{
return nil
}
let extent = inputImage.extent
let blur = createCustomKernel4().apply(
withExtent: inputImage.extent,
roiCallback:
{
(index, rect) in
return rect
},
arguments: [inputImage, inputBrightness as AnyObject])
return blur!.cropping(to: extent)
}
func createCustomKernel4() -> CIColorKernel {
let kernelString =
"kernel vec4 brightenEffect (sampler src , float k) { \n " +
" vec4 currentSource = sample (src, samplerCoord (src));" +
"currentSource.rgb = currentSource.rgb + k * currentSource.a;" +
"return currentSource; \n " +
"}"
return CIColorKernel(string: kernelString)!
//brigtens an image
}
}
class CustomFiltersVendor: NSObject, CIFilterConstructor
{
static func registerFilters()
{
CIFilter.registerName(
"CustomFilter",
constructor: CustomFiltersVendor(),
classAttributes: [
kCIAttributeFilterCategories: ["CustomFilters"]
])
}
func filter(withName name: String) -> CIFilter?
{
switch name
{
case "CustomFilter":
return CustomFilter()
default:
return nil
}
}
}
在我要使用的文件中,我有
let filter3 = CustomFilter()
filter3.setValue(coreImage, forKey: kCIInputImageKey)
filter3.inputKeys
let outputImage = filter3.outputImage!
我确实在inputKeys中看到了inputBrightness,但是我不知道如何修改它?我该怎么办?
最佳答案
答案较晚,但我遇到了这个问题。如果尚未创建,请子类CIFilter
。
您的内核代码表示您希望传递float k
的值。假设您希望将其称为inputBrightnessFactor
。这是您的子类中需要的:
class CustomFilter:CIFilter {
let kernel = CIColorKernel(source:
"kernel vec4 brightenEffect (sampler src , float k) { \n " +
"vec4 currentSource = sample (src, samplerCoord (src));" +
"currentSource.rgb = currentSource.rgb + k * currentSource.a;" +
"return currentSource; \n " +
"}")
var inputImage:CIImage!
var inputBrightnessFactor:Float = 1
override var attributes: [String : Any] {
return [
kCIAttributeFilterDisplayName: "My Custom Filter",
"inputImage": [kCIAttributeIdentity: 0,
kCIAttributeClass: "CIImage",
kCIAttributeDisplayName: "Image",
kCIAttributeType: kCIAttributeTypeImage],
"inputBrightnessFactor": [kCIAttributeIdentity: 0,
kCIAttributeClass: "NSNumber",
kCIAttributeDisplayName: "Brightness Factor",
kCIAttributeDefault: 0,
kCIAttributeMin: 0,
kCIAttributeSliderMin: 0,
kCIAttributeSliderMax: 1,
kCIAttributeType: kCIAttributeTypeScalar]
]
}
override init() {
super.init()
}
override func setValue(_ value: Any?, forKey key: String) {
switch key {
case "inputImage":
inputImage = value as! CIImage
case "inputBrightnessFactor":
inputBrightnessFactor = value as! Float
default:
break
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var outputImage: CIImage {
return kernel!.apply(extent: inputImage.extent, arguments: [inputImage as Any, inputBrightnessFactor as Any])!
}
}
需要注意的两个关键事项:
您可以覆盖
attributes
,以注册过滤器和属性的显示值,并为属性提供默认值。您可以覆盖
setValue(forKey:)
以使其像其他任何过滤器一样使用。用法(确保首先运行
CustomFilters.registerFilters()
):let myFactor:Float = 0.4
let filter = CIFilter(name: "CustomFilter")
filter.setValue(inputImage, forKey: kCIInputImageKey)
filter.setValue(myFactor, forKey: "inputBrightnessFactor")
let myOutputImage = filter?.outputImage
请注意,您现在像对待任何其他
CIFilter
一样对待内核。希望您已经把事情做好了,但是如果没有,应该去做。