Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange CoreImage cropping issues encounter here

I have a strange issue where after I cropped a photo from my photo library, it cannot be displayed from the App. It gives me this error after I run this code:

        self.correctedImageView.image = UIImage(ciImage: correctedImage)  

[api] -[CIContext(CIRenderDestination) _startTaskToRender:toDestination:forPrepareRender:error:] The image extent and destination extent do not intersect.

Here is the code I used to crop and display. (inputImage is CIImage)

    let imageSize = inputImage.extent.size
    let correctedImage = inputImage
        .cropped(to: textObvBox.boundingBox.scaled(to: imageSize) )
    DispatchQueue.main.async {
        self.correctedImageView.image = UIImage(ciImage: correctedImage)  
    }

More Info: Debug print the extent of the inputImage and correctedImage

Printing description of self.inputImage: CIImage: 0x1c42047a0 extent [0 0 3024 4032]>

crop [430 3955 31 32] extent=[430 3955 31 32] affine [0 -1 1 0 0 4032] extent=[0 0 3024 4032] opaque affine [1 0 0 -1 0 3024] extent=[0 0 4032 3024] opaque colormatch "sRGB IEC61966-2.1"_to_workingspace extent=[0 0 4032 3024] opaque IOSurface 0x1c4204790(501) seed:1 YCC420f 601 alpha_one extent=[0 0 4032 3024] opaque

Funny thing is that when I put a breakpoint, using Xcode, i was able to preview the cropped image properly. I'm not sure what this extent thing is for CIImage, but UIMageView doesn't like it when I assign the cropped image to it. Any idea what this extent thing does?

like image 814
mskw Avatar asked Dec 24 '22 13:12

mskw


1 Answers

I ran into the same problem you describe. Due to some weird behavior in UIKit / CoreImage, I needed to convert the CIImage to a CGImage first. I noticed it only happened when I applied some filters to the CIImage, described below.

let image = /* my CIImage */
let goodImage = UIImage(ciImage: image)
uiImageView.image = goodImage // works great!


let image = /* my CIImage after applying 5-10 filters */
let badImage = UIImage(ciImage: image)
uiImageView.image = badImage // empty view!

This is how I solved it.

let ciContext = CIContext()
let cgImage = self.ciContext.createCGImage(image, from: image.extent)
uiImageView.image = UIImage(cgImage: cgImage) // works great!!!

As other commenters have stated beware creating a CIContext too often; its an expensive operation.

like image 71
72A12F4E Avatar answered Dec 28 '22 06:12

72A12F4E