关于ios:如何将CIFilter应用于UIView?

How to apply CIFilter to UIView?

根据Apple docs,Apple docs,过滤器属性,iOS不支持。当我使用将CIFilter应用于UIView的应用程序之一时,即Splice,Funimate和artisto的视频编辑器Videoshow FX。这意味着我们可以将CIFilter应用于UIView

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


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

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

假设您要对CIPhotoEffectMono应用UIView。为此,请执行以下步骤:

  • UIView转换为CIImage
  • 应用过滤器,得到CIImage作为输出。
  • 使用CIContext创建CGImage,然后将其转换为UIImage

这里是UIView扩展名,它将视图及其所有子视图转换为UIImage

1
2
3
4
5
6
7
8
9
10
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是一行代码:

1
let ciInput =  CIImage(image: myView.createImage)

这是一个将应用过滤器并返回UIImage的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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!)
}