如何将CIFilter应用于UIView?
根据Apple docs,
iOS
不支持CALayer
filter属性。 因为我使用了其中一个将CIFilter
应用于UIView
的应用程序,即Splice,Video Editor Videoshow FX for Funimate和artisto。 这意味着我们可以将CIFilter
应用于UIView
。
我使用过SCRecorder
库并尝试通过SCPlayer
和SCFilterImageView
完成此任务。 但是在申请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!) }