简体   繁体   中英

createCGImage returns nil when attempting to rotate/crop an image using CIFilter

I am working on applying multiple CIFilters to an image but I keep getting a nil result when I apply the second filter. I've created crop and rotate functions as follows:

func crop(_ image: CIImage) -> CIImage?{
    let cropRectangle = CGRect(x: 0, y: 0, width: 0.5*image.extent.width, height: 0.5*image.extent.height)
    guard let filter = CIFilter(name: "CICrop") else {print("Could not create filter.");return nil}
    filter.setValue(image, forKey: "inputImage")
    filter.setValue(cropRectangle, forKey: "inputRectangle")
    return filter.outputImage
}

func rotate(image: CIImage, rotation: CGFloat) -> CIImage?{
    guard let filter = CIFilter(name: "CIAffineTransform") else {print("Unable to generate filter");return nil}
    let rotationTransform = CGAffineTransform.init(rotationAngle: rotation)
    filter.setValue(image, forKey: "inputImage")
    filter.setValue(rotationTransform, forKey: "inputTransform")
    return filter.outputImage
}

If I apply crop and then rotation, my context.createCGImage works fine, but when I apply rotate and then crop, it returns nil. I have checked the .extension on the CIImage I am attempting to crop to make sure the crop rectangle is within its bounds. Accepting ideas. Here's my call to the 2 above mentioned functtions:

let context = CIContext(options: nil)
        guard let ciImage = CIImage(image: #imageLiteral(resourceName: "sample3")) else {fatalError("Error on image generation!")}
        guard let ciRotated = self.rotate(image: ciImage, rotation: CGFloat(Double.pi*3/2)) else {print("Could not rotate.");return}
        guard let ciCropped = self.crop(ciRotated) else {print("Error cropping.");return}
        guard let final = context.createCGImage(ciCropped, from: ciCropped.extent) else {print("Error on CG gen.");return}

The problem was that the origin of the rotated image was no longer at 0,0, so the crop rectangle was really out of bounds, making the crop function return a 0x0 sized image. I added a translation to make the origin return to 0,0 and everything worked. Similar issue here: Core Image: after using CICrop, applying a compositing filter doesn't line up

Translation function I've created:

func translation(image: CIImage, x: CGFloat, y: CGFloat) -> CIImage?{
    guard let filter = CIFilter(name: "CIAffineTransform") else {print("Unable to generate filter"); return nil}
    let translate = CGAffineTransform.init(translationX: x, y: y)
    filter.setValue(image, forKey: "inputImage")
    filter.setValue(translate, forKey: "inputTransform")
    return filter.outputImage
}

Final call to this example:

            let context = CIContext(options: nil)
        guard let ciImage = CIImage(image: #imageLiteral(resourceName: "sample3")) else {fatalError("Error on image generation!")}
        guard let ciRotated = self.rotate(image: ciImage, rotation: CGFloat(Double.pi*3/2)) else {print("Could not rotate.");return}
        guard let ciTranslated = self.translation(image: ciRotated, x: 0, y: ciRotated.extent.height) else {print("Unable to translate."); return}
        guard let ciCropped = self.crop(ciTranslated) else {print("Error cropping.");return}
        guard let final = context.createCGImage(ciCropped, from: ciCropped.extent) else {print("Error on CG gen.");return}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM