Vitalii Vashchenko
Vitalii Vashchenko

Reputation: 1817

'CIImage is undeclared type' strange error

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

Upvotes: 15

Views: 4341

Answers (3)

Rudolf Adamkovič
Rudolf Adamkovič

Reputation: 31486

Use CoreImage.CIImage instead of CIImage to disambiguate.

Upvotes: 17

Ion
Ion

Reputation: 171

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)

Upvotes: 17

Yatheesha
Yatheesha

Reputation: 10432

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)

Upvotes: 7

Related Questions