5

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 i.e. 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.

Ved Rauniyar
  • 1,539
  • 14
  • 21
Rameez
  • 412
  • 1
  • 5
  • 16
  • I don't know about this , But the effect that you want you can achieve it by using GPUImage Framework also. That is much easier to use also. – Swifty Codes Sep 08 '17 at 12:04
  • Show some code. A typical error would be that you forgot to set `myView.wantsLayer = true` – Wukerplank Sep 08 '17 at 13:16
  • GPUImage Framework is applying filters only on live video not recorded video. I want to apply apply filters on already recorded video and also want to get preview of applied filter at runtime before export. – Rameez Sep 11 '17 at 06:46
  • @Rameez have you find any solution for this? I have same problem please help me as soon as possible. – Yogendra Patel Mar 20 '20 at 08:42
  • @YogendraPatel Yes my problem was solved but not with applying filter to UIView. Because we can't apply CIFilter to UIView. – Rameez Mar 20 '20 at 09:57
  • @Rameez Ok, please give me your other solution. – Yogendra Patel Mar 21 '20 at 12:24

1 Answers1

6

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!)
}
  • I tired your provided solution but i am getting only black screen. If i do try this solution on whole view then it is working because i have some visual controls in my screen i.e. buttons, top bar etc. But this solution is not working on a specific view i.e. my video player's view. My player view's background color is clear. – Rameez Sep 11 '17 at 06:40
  • I must not understand the issue then. First, a black screen possibly means you are using a blank image as input. But my confusion probably is surrounding on that "specific" view you want. Is that some type of a video screen? If so, while I *did* answer your question (it was asking for a `UIView`), you are right, simply turning a `UIView` into a `CIImage` for applying a CIFilter won't work. –  Sep 11 '17 at 09:04
  • Yes it is a video player's view. I want to apply filters on video. I can apply filters to that video by using AVMutableVideoComposition's applyingCIFiltersWithHandler callback constructor. As you know this callback will take some time to produce filtered video. But i want to give preview of filter at runtime to user. Just like applications are already providing this feature i.e. Splice, Video Editor Videoshow FX for Funimate and artisto. I know these apps are not applying filters directly to videos. They are using any type of image, uiview or layer. – Rameez Sep 11 '17 at 10:30
  • No, not *directly* to videos. Still, this isn't a simple `UIView` or static image. The best direction I could give you is this repo/blog - https://github.com/FlexMonkey/LiveCameraFiltering - it's in Swift 2, meaning you'll need to either use Xcode 8 to upgrade to Swift 3 or change the Swift Language Version in Xcode 9 and manually convert - but I think it'll help you. Good luck! –  Sep 11 '17 at 10:38
  • This library is dealing with live camera feed. But i checked his blog in detail. He also worked on recorded video and provided blog [link](http://flexmonkey.blogspot.nl/2016/04/loading-filtering-saving-videos-in-swift.html?showComment=1466655328057) . So this blog solved my problem as i expected. Thank you very much. Really appreciation from me. – Rameez Sep 12 '17 at 11:23
  • He's a great resource. His (now free) iBook, *Core Image for Swift* is highly recommended if you wish to write your own CIFilters. It's written in Swift 2 but most of the code doesn't change - and the largest change he wrote a blog post on there. –  Sep 12 '17 at 11:27
  • Well that's great. But this book is not yet available in pakistan store. – Rameez Sep 12 '17 at 11:54
  • Ow. Didn't know that. I checked the blog again, and here's a link for a "pay what you want" PDF: https://gumroad.com/l/CoreImageForSwift Here's the blog post - it has an embedded video: http://flexmonkey.blogspot.com/2016/05/core-image-for-swift-version-13.html?q=core+image+for+swift –  Sep 12 '17 at 11:58
  • Thanks man. I got the this pdf. This will be surely helpful regarding Core Image related tasks. – Rameez Sep 13 '17 at 12:41
  • Glad to have helped. Even though my answer isn't a correct one for your issue, I'll keep it posted for others down the road. (Unless you want me to delete it.) –  Sep 13 '17 at 13:18