swift - 如何修改自定义 CIFilter 的 inputKeys?

标签 swift

我正在尝试创建一个自定义 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])!
    }
}

值得注意的两个关键事项:

  • 您可以覆盖属性来注册过滤器和属性的显示值,并为属性指定默认值。
  • 您可以重写 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 一样对待您的内核。

希望您已经开始工作,但如果没有,也应该这样做。

关于swift - 如何修改自定义 CIFilter 的 inputKeys?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44571898/

相关文章:

ios - UICollectionView 的反向对齐

arrays - 快速查找值 json 数组

ios - 为 webView 添加分享功能 - iOS

ios - Swift Playground 协议(protocol)在固定迭代次数后崩溃

swift - 未调用 UISearchController 委托(delegate)方法,搜索栏无法成为第一响应者

ios - 删除核心数据中的第一个对象(Swift)

swift - self.tabBarController.selectedIndex 不调用 viewDidAppear

ios - 拖动 super View 时更新 UILabel 的文本

ios - 分页 UIScrollView 似乎使内容偏离中心

ios - UIPageViewController 显示错误数据