4

In a Swift playground, I am loading a JPEG, converting it to a UIImage and filtering it to monochrome. I then convert the resulting filtered image to a UIImage.

The input and the filtered images display correctly.

I then convert both images to a CGImage type. This works for the input image, but the filtered image returns nil from the conversion:

// Get an input image
let imageFilename = "yosemite.jpg"
let inputImage = UIImage(named: imageFilename )
let inputCIImage = CIImage(image:inputImage!)

// Filter the input image - make it monochrome
let filter = CIFilter(name: "CIPhotoEffectMono")
filter!.setDefaults()
filter!.setValue(inputCIImage, forKey: kCIInputImageKey)
let CIout = filter!.outputImage
let filteredImage = UIImage(CIImage: CIout!)        

// Convert the input image to a CGImage
let inputCGImageRef = inputImage!.CGImage           // Result: <CGImage 0x7fdd095023d0>
// THE LINE ABOVE WORKS

// Try to convert the filtered image to a CGImage
let filteredCGImageRef = filteredImage.CGImage      // Result: nil
// THE LINE ABOVE DOES NOT WORK
// Note that the compiler objects to 'filteredImage!.CGImage'

What's wrong?

Simon Youens
  • 177
  • 1
  • 13

1 Answers1

6

A UIImage created from a CIImage as you've done isn't backed by a CGImage. You need to explicitly create one:

let context = CIContext()
let filteredCGImageRef = context.createCGImage(
    CIout!, 
    fromRect: CIout!.extent)

If you need a UIImage, create that from the CGImage rendered by the CIContext:

UIImage(CGImage: filteredCGImageRef)

Cheers,

Simon

Flex Monkey
  • 3,583
  • 17
  • 19
  • Perfect - exactly what I needed. – Simon Youens May 08 '16 at 05:43
  • I had the exact same challenge as Simon Youens of my CIFiltered UIImage returning nil when converting it to a cgImage using .cgImage, and creating a CGImage using this explicit CIContext() method solved this for me also. Thanks greatly! – Isaac A Feb 22 '20 at 15:22