CIFilter 的输出图像为空。

8

我正在使用核心图像,并对我的图像应用CIFilter棕褐色调。在viewDidLoad中运行一次滤镜,然后立即调用另一个函数再次添加滤镜。出于某种原因,当我尝试访问输出图像时,应用程序会崩溃并显示输出图像为空。有人知道这是为什么吗?

谢谢

    import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var myimage: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let image = CIImage(image: myimage.image)
        let filter = CIFilter(name: "CISepiaTone")
        filter.setDefaults()
        filter.setValue(image, forKey: kCIInputImageKey)
        myimage.image = UIImage(CIImage: filter.outputImage)
        self.reapplyFilter()
    }

        func reapplyFilter(){
            let image = CIImage(image: myimage.image)
            let filter = CIFilter(name: "CISepiaTone")
            filter.setDefaults()
            filter.setVa    lue(image, forKey: kCIInputImageKey)
    //ERROR HERE: fatal error: unexpectedly found nil while unwrapping an Optional value
            myimage.image = UIImage(CIImage: filter.outputImage)
//ERROR
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }



}
2个回答

12

您不能调用UIImage(CIImage:)并将该UIImage用作UIImageView的图像。UIImageView需要由位图(CGImage)支持的UIImage。使用CIImage实例化的UIImage没有位图;它没有实际的图像,只是一组应用滤镜的指令。这就是为什么您的UIImageView的图像为nil的原因。


请查看我的书,了解如何从CIImage中提取出一个真实的图像:http://www.apeth.com/iOSBook/ch15.html#_cifilter_and_ciimage - matt
1
对于Swift代码,请访问以下链接:https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch02p070filters/ch15p419filters/ViewController.swift - matt
1
我发现 http://stackoverflow.com/users/1955870/fz 提出的解决方案是有效的(使用 CIContext)。是否存在相关风险? - SwiftArchitect
1
@SwiftArchitect 那个答案就是我所说的要做的。这与调用UIImage(CIImage:)并将其放入图像视图完全不同;这正是我所说的不要做的。- 还请参阅我的书:http://www.apeth.com/iOSBook/ch15.html#_cifilter_and_ciimage - matt
@SwiftArchitect 链接到一个用户。更有用的是,这里是他所指的 答案链接。这展示了正确编写此代码的方式。 - ToolmakerSteve

9

有几个要点需要注意:

1)使用CIImage构造器基于非CIImage支持的UIImage创建CIImage是危险的,可能会返回nil或空的CIImage。

2)在创建图像时,建议您使用CIContext而不是UIImage(CIImage:)。

示例:

class ViewController: UIViewController {
    @IBOutlet weak var myimage: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        myimage.backgroundColor = UIColor.redColor()

        self.applyFilter()
        self.applyFilter()
    }

    func applyFilter(){
        let image = CIImage(CGImage: myimage.image?.CGImage)
        let filter = CIFilter(name: "CISepiaTone")
        filter.setDefaults()
        filter.setValue(image, forKey: kCIInputImageKey)

        let context = CIContext(options: nil)
        let imageRef = context.createCGImage(filter.outputImage, fromRect: image.extent())
        myimage.image = UIImage(CGImage: imageRef)
    }
}

太好了!我创建了一个 IBInspectable UIImageView 并将代码发布在 https://gist.github.com/SwiftArchitect/676007e8e1c77e632520 上。 - SwiftArchitect

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接