2

我正在写代码。这是我的完整源代码。

我确认我的代码在 Xcode 8.3.3 中成功运行。

但是,我的代码在 Xcode 9.x(9.1 和 9.2)中崩溃了。

确切地说,我的代码在“filter.setValue(inputCIImage, forKey: kCIInputImageKey)”和“NSException (sig abrt)”中崩溃了

即使我使用了调试器,我也没有找到原因。

Xcode 8.3.3 的结果

import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!

let inputImage = UIImage(named: "testImage.png")

override func viewDidLoad() {
    super.viewDidLoad()
    let inputCIImage = CIImage(image: inputImage!)

    let filter = CustomFilter()
    filter.setValue(inputCIImage, forKey: kCIInputImageKey)
    let outputImage = filter.outputImage!
    let context = CIContext()
    let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent)
    imageView.image = UIImage(cgImage: outputCGImage!)
}
}

class CustomFilter: CIFilter {
var inputImage: CIImage?

override public var outputImage: CIImage! {
    get {
        if let inputImage = self.inputImage {
            let args = [inputImage as AnyObject]
            return createCustomKernel().apply(extent: inputImage.extent, arguments: args)
        } else {
            return nil
        }
    }
}

func createCustomKernel() -> CIColorKernel {
    let kernelString =
        "kernel vec4 chromaKey(__sample s){\n" +
            "vec4 newPixel = s.rgba;\n" +
            "newPixel[0] = 0.0;\n" +
            "newPixel[2] = newPixel[2] / 2.0;\n" +
            "return newPixel;\n" + "}"
    return CIColorKernel(source: kernelString)!
}
}
4

1 回答 1

1

我能够使用的唯一方法setValue(forKey:)是实际注册我的自定义过滤器。诚然,我只在 Swift 4 应用程序中这样做过,但我很惊讶这在 Swift 3 中有效。

请记住,虽然 `setValue(forKey:) 在语法上是有效的——这意味着它会构建——但当 CoreImage 尝试执行你的过滤器时,就会出现任何错误。

我认为你有两个选择:

(1) 最简单的方法是更改​​您传递输入图像的方式(这是自 Swift 2 以来我所做的事情)。尝试用以下代码替换该行:

filter.inputImage = inputCIImage

(2) 注册您的过滤器。在您的CustomFilter班级中,添加以下内容:

var inputImage: CIImage!

override var attributes: [String : Any] {
    return [
        kCIAttributeFilterDisplayName: "My custom filter",

        "inputImage": [kCIAttributeIdentity: 0,
                       kCIAttributeClass: "CIImage",
                       kCIAttributeDisplayName: "Image",
                       kCIAttributeType: kCIAttributeTypeImage]
    ]
}

接下来,子类CIFilterConstructor

class CustomFilters: NSObject, CIFilterConstructor {
    static func registerFilters() {
        CIFilter.registerName(
            "My custom filter",
            constructor: CustomFilters(),
            classAttributes: [
                kCIAttributeFilterCategories: [CategoryCustom]
            ])
    }
    func filter(withName name: String) -> CIFilter? {
        switch name {
        case "My custom filter":
            return CustomFilter()
        default:
            return nil
        }
    }
}

最后,在您的应用程序代码中,执行以下两件事:

(A) 注册您的过滤器。我通常这样做viewDidLoad

CustomFilters.RegisterFilters()

(B) 实例化您的过滤器,按名称调用它:

let filter = CIFilter(name: "My custom filter")
于 2017-12-08T18:08:22.580 回答