0

I'm trying to apply filters on images. Applying the filter works great, but it mirrors the image vertically.

The bottom row of images calls the filter function after init.

The main image at the top, gets the filter applied after pressing on one at the bottom

The ciFilter is CIFilter.sepiaTone().

func applyFilter(image: UIImage) -> UIImage? {
        let rect = CGRect(origin: CGPoint.zero, size: image.size)
        let renderer = UIGraphicsImageRenderer(bounds: rect)

        ciFilter.setValue(CIImage(image: image), forKey: kCIInputImageKey)
        
        let image = renderer.image { context in
            let ciContext = CIContext(cgContext: context.cgContext, options: nil)

            if let outputImage = ciFilter.outputImage {
                ciContext.draw(outputImage, in: rect, from: rect)
            }
        }

        return image
    }

And after applying the filter twice, the new image gets zoomed in.

Here are some screenshots. Start After applying the filter After applying the filter the second time

Daniel
  • 50
  • 1
  • 7
  • UIKit origin is top left, but CIFilter origin is bottom left. You have to compensate. – matt Mar 31 '21 at 07:16

1 Answers1

0

You don't need to use UIGraphicsImageRenderer. You can directly get the image from CIContext.

func applyFilter(image: UIImage) -> UIImage? {
        
        ciFilter.setValue(CIImage(image: image), forKey: kCIInputImageKey)
        
        guard let ciImage = ciFilter.outputImage else {
            return nil
        }
        let outputCGImage = CIContext().createCGImage(ciImage, from: ciImage.extent)
        
        guard let _ = outputCGImage else { return nil }
        let filteredImage = UIImage(cgImage: outputCGImage!, scale: image.scale, orientation: image.imageOrientation)
        
        return filteredImage
    }
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • This works, but uses way more memory, than UIGraphicsImageRenderer. Thats why, I don't want to use this approach. – Daniel Mar 31 '21 at 07:39
  • In your function you can try this : return UIImage(cgImage: image.cgImage!, scale: image.scale, orientation: image.imageOrientation) – Raja Kishan Mar 31 '21 at 07:43
  • image.cgImage and image.ciImage is always nil. I already tried that too. – Daniel Mar 31 '21 at 07:55
  • Have you tried this : ```CIImage(image: image)?.cgImage``` – Raja Kishan Mar 31 '21 at 07:57
  • I don't know why, but it's still nil. But i got a console Output: ```CGBitmapContextCreateWithCallbacks: failed to create CGAutomaticBitmapContextInfo.``` – Daniel Mar 31 '21 at 08:05