【问题标题】:Custom Filter of Core Image and "sig abrt" in Xcode 9.xXcode 9.x 中 Core Image 和“sig abrt”的自定义过滤器
【发布时间】:2018-05-21 07:20:07
【问题描述】:

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

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

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

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

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

result of 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)!
}
}

【问题讨论】:

    标签: swift xcode9 core-image cifilter cikernel


    【解决方案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")
    

    【讨论】:

    • 谢谢。您的回答很有帮助。
    猜你喜欢
    • 2015-11-11
    • 2012-02-12
    • 2019-04-30
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2018-03-06
    • 1970-01-01
    相关资源
    最近更新 更多