如何将CIFilter应用于UIView?

5
根据苹果文档,iOS不支持CALayerfilters属性。但是我使用了一些应用程序,如Splice、Video Editor Videoshow FX for Funimate和artisto,它们将CIFilter应用于UIView。这意味着我们可以将CIFilter应用于UIView
我使用了SCRecorder库,并尝试通过SCPlayerSCFilterImageView完成此任务。但是当视频播放后应用了CIFilter时,我遇到了黑屏问题。因此,请帮助我完成这个任务,以便我可以将CIFilter应用于UIView,并且可以通过单击UIButton更改过滤器。

我不太清楚这个,但是你想要的效果也可以通过使用GPUImage框架来实现。而且使用起来更加容易。 - Swifty Codes
展示一些代码。一个典型的错误是您忘记设置myView.wantsLayer = true - Wukerplank
GPUImage框架仅适用于实时视频而非录制视频。我想在已录制的视频上应用滤镜,并且在导出之前希望能够实时预览应用的滤镜效果。 - Rameez
@Rameez,你找到解决方案了吗?我也遇到了同样的问题,请尽快帮助我。 - Yogendra Patel
@YogendraPatel 是的,我的问题已经解决了,但不是通过将滤镜应用于UIView。因为我们不能将CIFilter应用于UIView。 - Rameez
@Rameez 好的,请给我你的另一个解决方案。 - Yogendra Patel
1个回答

6
技术上来讲,CIFilter需要一个CIImage。可以将UIView转换为UIImage,然后将其转换为CIImage,但所有使用图像作为输入的CoreImage滤镜(有一些生成新图像)都使用CIImage作为输入和输出。

  • 请注意,CIImage的原点在左下角,而不是左上角,即y轴被翻转。
  • 如果动态使用CoreImage过滤器,请学会使用GLKView进行渲染-它使用GPU,而UIImageView使用CPU。
  • 如果您想测试滤镜,最好使用实际设备。模拟器将给出非常低的性能。我曾看到一个简单的模糊效果花费了近一分钟的时间,在设备上只需几分之一秒!

假设您有一个UIView,希望对其应用CIPhotoEffectMono。要执行此操作的步骤如下:

  • UIView转换为CIImage
  • 应用滤镜,获取一个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)

以下是一个应用过滤器并返回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!)
}

是的,这是一个视频播放器的视图。我想在视频上应用滤镜。我可以使用AVMutableVideoComposition的applyingCIFiltersWithHandler回调构造函数对该视频应用滤镜。正如您所知,此回调需要一些时间来生成经过滤镜处理的视频。但我想在运行时向用户提供滤镜预览。就像应用程序已经提供了这个功能,即Splice、Video Editor Videoshow FX for Funimate和artisto。我知道这些应用程序不会直接将滤镜应用于视频。它们使用任何类型的图像、uiview或层。 - Rameez
不,不是直接用视频。但这不是一个简单的 UIView 或静态图像。我能给你的最好方向是这个仓库/博客 - https://github.com/FlexMonkey/LiveCameraFiltering - 它是用 Swift 2 编写的,这意味着你需要使用 Xcode 8 升级到 Swift 3 或在 Xcode 9 中更改 Swift 语言版本并手动转换 - 但我认为它会对你有所帮助。祝你好运! - user7014451
他是一个非常好的资源。如果你想要编写自己的CIFilters,他的(现在免费的)iBook《Swift核心图像》强烈推荐阅读。它是用Swift 2编写的,但大部分代码不会改变 - 而且他在博客文章中写了最大的变化。 - user7014451
那很好。但是这本书在巴基斯坦商店还没有上架。 - Rameez
哦,我不知道。我再次检查了博客,并提供了一个“随意付款”的PDF链接:https://gumroad.com/l/CoreImageForSwift。这是博客文章-它有一个嵌入式视频:http://flexmonkey.blogspot.com/2016/05/core-image-for-swift-version-13.html?q=core+image+for+swift - user7014451
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接