如何将CIFilter应用于UIView?

根据Apple docs, iOS不支持CALayerfilter属性。 因为我使用了其中一个将CIFilter应用于UIView的应用程序,即Splice,Video Editor Videoshow FX for Funimate和artisto。 这意味着我们可以将CIFilter应用于UIView

我使用过SCRecorder库并尝试通过SCPlayerSCFilterImageView完成此任务。 但是在申请CIFilter后播放video时我面临黑屏问题。 请帮助我完成此任务,以便我可以将CIFilter应用于UIView ,也可以通过单击UIButton来更改filter。

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

  • 请注意, CIImage的原点是左下角,而不是左上角。 基本上Y轴是翻转的。
  • 如果您动态使用CoreImagefilter,请学习使用GLKView进行渲染 – 它使用UIImageView使用CPU的GPU。
  • 如果要测试filter,最好使用实际设备。 模拟器会给你很差的性能。 我已经看到一个简单的模糊需要将近一分钟的时间在设备上它将是一小部分秒!

假设您有一个想要应用CIPhotoEffectMono的UIView 。 执行此操作的步骤将是:

  • UIView转换为CIImage
  • 应用filter,获取CIImage作为输出。
  • 使用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! } } 

UIImage转换为CIImage是一行代码:

 let ciInput = CIImage(image: myView.createImage) 

这是一个将应用filter并返回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!) }