-->

Converting UIImage to CIImage Returns nil

2019-09-19 18:19发布

问题:

I'm trying to convert the UIImage from an imageView into a CIImage for the purpose of filtering it. However, I cannot get the CIImage to have a value.

In the simplest form, here's what I am trying:

let ciInput = CIImage(image: imageView.image!)

but the ciInput always is nil. I have also tried

let ciInput = CIImage(cgImage: imageView.image!.cgImage)

but also returns nil.

(imageView.image is not nil, but imageView.image!.cgImage and imageView.image!.ciImage are both nil)

I need to convert the UIImage from the imageView into a valid CIImage. Any help is appreciated, thanks!

EDIT: Here is the full function code

func makeWhiteTransparent(imageView: UIImageView) {

    let invertFilter = CIFilter(name: "CIColorInvert")
    let ciContext = CIContext(options: nil)

    let ciInput = CIImage(image: imageView.image!) //This is nil
    invertFilter?.setValue(ciInput, forKey: "inputImage")

    let ciOutput = invertFilter?.outputImage
    let cgImage = ciContext.createCGImage(ciOutput!, from: (ciOutput?.extent)!)

    imageView.image = UIImage(cgImage: cgImage!)
}

When running this function, I get a fatal unwrapping nil error on the last line. Using the debugger, I discovered that the ciInput is nil, which it should not be.

EDIT 2: The image on the imageView before calling makeWhiteTransparent is a QR code generated with this function:

func generateQRCode(from string: String) -> UIImage? {
    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")

        let transform = CGAffineTransform(scaleX: 12, y: 12)

        if let output = filter.outputImage?.applying(transform) {
            return UIImage(ciImage: output)
        }
    }

    return nil
}

回答1:

So the problem was in my QR Code generation. The code returned a UIImage from a CIImage without properly utilizing CGContext to return the UIImage. Here is the corrected QR Code function that fixed the issue.

func generateQRCode(from string: String) -> UIImage? {
    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")

        let transform = CGAffineTransform(scaleX: 12, y: 12)

        if let output = filter.outputImage?.applying(transform) {
            let context = CIContext()
            let cgImage = context.createCGImage(output, from: output.extent)
            return UIImage(cgImage: cgImage!)
        }
    }

    return nil
}