简体   繁体   中英

How to apply CIFilter to UIView?

According to Apple docs, filters property of CALayer is not supported in iOS . As i used one of the apps which are applying CIFilter to UIView ie Splice, Video Editor Videoshow FX for Funimate and artisto. That's means we can apply CIFilter to UIView .

I have used SCRecorder library and try to get this task done by SCPlayer and SCFilterImageView . But i am facing black screen issue when video is playing after apply CIFilter . So kindly help me to complete this task so that i can apply CIFilter to UIView and also can change the filter by clicking on a UIButton.

The technically accurate answer is that a CIFilter requires a CIImage . You can turn a UIView into a UIImage and then convert that into a CIImage , but all CoreImage filters that use an image for input (there are some that generate a new image) use a `CIImage for input and output.

  • Please note that the origin for a CIImage is bottom left, not top left. Basically the Y axis is flipped.
  • If you use CoreImage filters dynamically, learn to use a GLKView to render in - it uses the GPU where a UIImageView uses the CPU.
  • If you want to test out a filter, it's best to use an actual device. The simulator will give you very poor performance. I've seen a simple blur take nearly a minute where on a device it will be a fraction of a second!

Let's say you have a UIView that you wish to apply a CIPhotoEffectMono to. The steps to do this would be:

  • Convert the UIView into a CIImage .
  • Apply the filter, getting a CIImage as output.
  • Use a CIContext to create a CGImage and then convert that to a UIImage .

Here's a UIView extension that will convert the view and all it's subviews into a UIImage :

extension UIView {
    public func createImage() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(
            CGSize(width: self.frame.width, height: self.frame.height), true, 1)
        self.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}

Converting a UIImage into a CIImage is one line of code:

let ciInput =  CIImage(image: myView.createImage)

Here's a function that will apply the filter and return a UIImage :

func convertImageToBW(image:UIImage) -> UIImage {

    let filter = CIFilter(name: "CIPhotoEffectMono")

    // convert UIImage to CIImage and set as input

    let ciInput = CIImage(image: image)
    filter?.setValue(ciInput, forKey: "inputImage")

    // get output CIImage, render as CGImage first to retain proper UIImage scale

    let ciOutput = filter?.outputImage
    let ciContext = CIContext()
    let cgImage = ciContext.createCGImage(ciOutput!, from: (ciOutput?.extent)!)

    return UIImage(cgImage: cgImage!)
}

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