0

I'm having trouble combining two images together with CIFilter. What is going wrong here?

The below code creates a UIImageView and adds it to the view, then combines two images imageA and imageB with a CIFilter, and outputs the composite into the UIImageView.

However, the combined image is not displayed in the UIImageView, it remains blank.


Questions:

  1. What is the correct code to display the composite image into the UIImageView?
  2. Is there more performant way in which to combine two images with CIFilter?

Code:

    let imageView = UIImageView()
    imageView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
    imageView.contentMode = .Center
    view.addSubview(imageView)

    let imageA = CIImage(image: UIImage(named:"imageA")!)
    let imageB = CIImage(image: UIImage(named:"imageB")!)
    let imageFilter = CIFilter(name: "CIAdditionCompositing")!

    imageFilter.setValue(imageA, forKey: kCIInputImageKey)
    imageFilter.setValue(imageB, forKey: kCIInputBackgroundImageKey)

    if let imageCombined = imageFilter.outputImage {
        let image = UIImage(CIImage: imageCombined)
        imageView.image = image
    }
user4806509
  • 2,925
  • 5
  • 37
  • 72

1 Answers1

1

I've always had issues with straight UIImage << >> CIImage conversions. If you have a frame/size/extent you can work with, I recommend using a CIContext and creating a CGImage first:

let ciContext = CIContext(options: nil)
let cgImg = ciContext.createCGImage(imageCombined, from: imageCombined.extent)
let uiImage = UIImage(cgImage: cgImg!)

Remember that creating a CIContext is "costly", so if you need to do this for multiple images, create one and use it for all rendering. Also, if you are using a GLKView someplace, use it's context.

Regards to question #2, your code looks fine. You could "combine lines of code but that does not affect performance. CoreImage doesn't "process" anything until you call for a filter's outputImage.

  • Thanks @dfd . I'll give this a go shortly. Any particular reason why straight UIImage << >> CIImage conversions could cause some issues? Is there an even better optimised way to combine images that are better for performance? – user4806509 Dec 18 '17 at 15:18
  • I honestly don't know why a straight conversion is flaky. I've always used the method above. That, combined with displaying things in a `GLKView`, is very good performance-wise. You can use this (along with sliders attached to input parameters) to achieve "real-time" filter rendering. Then, and only when needed, convert to a `UIImage`. One thing to remember - CoreImage (and GLKViews) are optimized to use the GPU. Testing in the simulator **will** give you poor performance. Before thinking you have a performance issue, try it on a real device. –  Dec 18 '17 at 15:24
  • Thanks very much @dfd for all that explanation. – user4806509 Dec 18 '17 at 15:29