Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'CIImage is undeclared type' strange error

Tags:

xcode

ios

swift

Please, help to understand what's wrong here. I've tried both Xcode 6.0.1 and Xcode 6.1 beta 2. I have a simple extension.

extension UIImage {
    func saturate (toLevel level : Float) -> UIImage {
        // create filter
        let saturationFilter = CIFilter(name: "CIColorControls")
        saturationFilter.setValue(self.CIImage, forKey: kCIInputImageKey)
        saturationFilter.setValue(NSNumber.numberWithFloat(level), forKey: "inputSaturation")

        // create context
        let context = CIContext(options: nil)

        // render image with filter
ERROR:  let renderedImage = saturationFilter.valueForKey(kCIOutputImageKey) as CIImage
        let imageRef = context.createCGImage(renderedImage, fromRect: renderedImage.extent())

        return UIImage(CGImage: imageRef)
    }
}

But the compiler says "Use of undeclared type 'CIImage'". What the hell? I've tried to import CoreImage, but nothing changed

like image 926
Vitalii Vashchenko Avatar asked Sep 22 '14 05:09

Vitalii Vashchenko


3 Answers

Use CoreImage.CIImage instead of CIImage to disambiguate.

like image 187
Rudolf Adamkovič Avatar answered Nov 13 '22 20:11

Rudolf Adamkovič


In order to avoid the bug you can define a type alias.

typealias MYImage = CIImage

Then declare the input CIImage in your category as:

let inputImage = MYImage(image: self)
like image 21
Ion Avatar answered Nov 13 '22 22:11

Ion


Seems to be bug in Xcode ,typecasting Fails only inside the extension block, You can directly access the output image using the property 'outputImage' which is of CIImage type. No need to use valueForKey, Try below code

 extension UIImage {
        func saturate (toLevel level : Float) -> UIImage {
            // create filter
            let saturationFilter = CIFilter(name: "CIColorControls")
            saturationFilter.setValue(self.CIImage, forKey: kCIInputImageKey)
            saturationFilter.setValue(NSNumber.numberWithFloat(level), forKey: "inputSaturation")

            // create context
            let context = CIContext(options: nil)

            // render image with filter
        let renderedImage = saturationFilter.outputImage
         let imageRef = context.createCGImage(renderedImage, fromRect: renderedImage.extent())

            return UIImage(CGImage: imageRef)
        }
    }

************************ Update ***********************

I think In your case ciImage property of UIImage instance is nil , that's why its crashing. Note that UIImage is not in fact a CIImage. In other words, UIImage's CIImage is not nil only if the UIImage is backed by a CIImage already (e.g. because it was generated by imageWithCIImage:). You can't use this to magically turn the UIImage into a CIImage, as you seem to be hoping to do.

So you need to initialise image with a CIImage instance, Try like this to get rid of crash

    let image = UIImage(named: "test")

    let ciImage = CIImage(image: image)

    let imageWithCIImage = UIImage(CIImage: ciImage)

    imageWithCIImage.saturate(toLevel: 0.5)
like image 7
Yatheesha Avatar answered Nov 13 '22 20:11

Yatheesha