如何将CIFilter应用于UIView?

Ram*_*eez 3 objective-c uiview ios cifilter swift

根据Apple docs,过滤器属性CALayer不支持iOS.正如我所使用其应用的应用程序之一CIFilter,以UIView即熔接,视频编辑器Videoshow FX为Funimate和artisto.这是我们可以运用的手段CIFilterUIView.

我已经使用过SCRecorder库并尝试通过SCPlayer和完成此任务SCFilterImageView.但申请后播放视频时我面临黑屏问题CIFilter.所以好心帮我完成这个任务,这样我可以申请CIFilterUIView,也可以通过点击一个UIButton更换过滤器.

dfd*_*dfd 5

技术上准确的答案是a CIFilter需要a CIImage.您可以将a UIView转换为a UIImage然后将其转换为a CIImage,但所有使用图像进行输入的CoreImage过滤器(有一些生成新图像)使用`CIImage进行输入和输出.

  • 请注意,a的原点CIImage是左下角,而不是左上角.基本上Y轴被翻转.
  • 如果动态使用CoreImage过滤器,请学会使用a GLKView来渲染 - 它使用GPU来UIImageView使用CPU.
  • 如果要测试过滤器,最好使用实际设备.该模拟器会给你非常表现不佳.我已经看到一个简单的模糊需要将近一分钟,在设备上它将是一小部分秒!

假设你有一个UIView你希望应用CIPhotoEffectMono的.执行此操作的步骤将是:

  • 转换UIView成a CIImage.
  • 应用过滤器,获得CIImage输出.
  • 使用a CIContext创建一个CGImage然后将其转换为UIImage.

这是一个UIView扩展,它将视图及其所有子视图转换为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!
    }
}
Run Code Online (Sandbox Code Playgroud)

将a UIImage转换为a CIImage是一行代码:

let ciInput =  CIImage(image: myView.createImage)
Run Code Online (Sandbox Code Playgroud)

这是一个将应用过滤器并返回一个函数的函数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!)
}
Run Code Online (Sandbox Code Playgroud)