【问题标题】:How to apply CIFilter to UIView?如何将 CIFilter 应用于 UIView?
【发布时间】:2018-02-17 07:59:00
【问题描述】:

根据 Apple docs,CALayer 的过滤器属性在 iOS 中不受支持。因为我使用了将CIFilter 应用到UIView 的应用程序之一,即 Splice,用于 Funimate 和 Artisto 的视频编辑器 Videoshow FX。这意味着我们可以将CIFilter 应用于UIView

我使用了SCRecorder 库并尝试让SCPlayerSCFilterImageView 完成这项任务。但是我在应用CIFilter 后播放视频时遇到黑屏问题。所以请帮助我完成这项任务,以便我可以将CIFilter 应用到UIView 并且还可以通过单击 UIButton 来更改过滤器。

【问题讨论】:

  • 这个我不知道,但是你想要的效果也可以通过GPUImage框架来实现。这也更容易使用。
  • 显示一些代码。一个典型的错误是您忘记设置myView.wantsLayer = true
  • GPUImage 框架仅对实时视频而不是录制的视频应用过滤器。我想在已录制的视频上应用过滤器,还想在导出前在运行时预览应用的过滤器。
  • @Rameez 你找到解决方案了吗?我有同样的问题,请尽快帮助我。
  • @YogendraPatel 是的,我的问题已解决,但未将过滤器应用于 UIView。因为我们不能将 CIFilter 应用到 UIView。

标签: ios objective-c swift uiview cifilter


【解决方案1】:

技术上准确的答案是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!)
}

【讨论】:

  • 我厌倦了您提供的解决方案,但我得到的只是黑屏。如果我确实在整个视图上尝试此解决方案,那么它可以正常工作,因为我的屏幕中有一些视觉控件,即按钮、顶栏等。但此解决方案不适用于特定视图,即我的视频播放器的视图。我的播放器视图的背景颜色清晰。
  • 那我一定不明白这个问题。首先,黑屏可能意味着您正在使用空白图像作为输入。但是我的困惑可能围绕着您想要的“特定”视图。那是某种类型的视频屏幕吗?如果是这样,虽然我确实回答了您的问题(它要求UIView),但您是对的,只需将UIView 转换为CIImage 以应用CIFilter 将不起作用.
  • 是的,它是视频播放器的视图。我想对视频应用过滤器。我可以使用 AVMutableVideoComposition 的 applicationsCIFiltersWithHandler 回调构造函数将过滤器应用于该视频。如您所知,此回调将需要一些时间来生成过滤视频。但我想在运行时向用户提供过滤器的预览。就像应用程序已经提供此功能一样,例如 Splice、视频编辑器 Videoshow FX for Funimate 和 Artisto。我知道这些应用程序没有直接对视频应用过滤器。他们使用任何类型的图像、uiview 或图层。
  • 不,不是直接到视频。不过,这不是一个简单的UIView 或静态图像。我能给你的最好的方向是这个 repo/blog - github.com/FlexMonkey/LiveCameraFiltering - 它在 Swift 2 中,这意味着你需要使用 Xcode 8 升级到 Swift 3 或在 Xcode 9 中更改 Swift 语言版本并手动转换 -但我认为它会帮助你。祝你好运!
  • 这个库正在处理实时摄像机源。但我详细查看了他的博客。他还负责录制视频并提供博客link。所以这个博客如我所料解决了我的问题。非常感谢。真的很感谢我。
猜你喜欢
  • 2014-07-14
  • 2012-03-30
  • 1970-01-01
  • 2015-06-08
  • 2014-03-28
  • 1970-01-01
  • 2015-02-18
  • 2012-05-05
  • 1970-01-01
相关资源
最近更新 更多