ios - 如何在 iOS 中将 Vignette CIFilter 应用到实时摄像头源?

标签 ios avfoundation core-image cifilter metalkit

在尝试将简单的晕影滤镜应用于 iPhone6 的原始相机源时,在 Metal 和 Core Image 的帮助下,我发现在 MTKView 中处理和渲染的帧之间存在很大的延迟

我遵循的方法是(MetalViewController.swift):

  1. 使用 AVCaptureVideoDataOutputSampleBufferDelegate 获取原始相机输出
  2. 转换CMSampleBuffer > CVPixelBuffer > CGImage
  3. 使用此 CGImage 创建一个 MTLTexture

点号2 和 3 位于名为:fillMTLTextureToStoreTheImageData

的方法内
  • CIFilter 应用于从 MTKViewDelegate 中的 MTLTexture 获取的 CIImage
  •     func draw(in view: MTKView) {
    
            if let currentDrawable = view.currentDrawable {
                let commandBuffer = self.commandQueue.makeCommandBuffer()
    
                if let myTexture = self.sourceTexture{
    
                    let inputImage = CIImage(mtlTexture: myTexture, options: nil)
    
                    self.vignetteEffect.setValue(inputImage, forKey: kCIInputImageKey)
    
                    self.coreImageContext.render(self.vignetteEffect.outputImage!, to: currentDrawable.texture, commandBuffer: commandBuffer, bounds: inputImage!.extent, colorSpace: self.colorSpace)
    
                    commandBuffer?.present(currentDrawable)
    
                    commandBuffer?.commit()
                }
            }
        }
    

    性能根本不是苹果在本文档中提到的:https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html#//apple_ref/doc/uid/TP30001185-CH3-TPXREF101

    我错过了什么吗?

    最佳答案

    您的第 2 步太慢,无法支持实时渲染...而且看起来您错过了几个步骤。为了您的目的,您通常会:

    设置:

    1. 创建 CVPixelBuffer 池 - 使用 CVPixelBufferPoolCreate
    2. 使用CVMetalTextureCacheCreate创建金属纹理池

    对于每一帧:

  • 转换CMSampleBuffer > CVPixelBuffer > CIImage
  • CIImage 通过过滤器管道
  • 将输出图像从第 1 步中创建的池中渲染到 CVPixelBuffer
  • 使用 CVMetalTextureCacheCreateTextureFromImage 使用过滤后的 CVPixelBuffer 创建金属纹理
  • 如果设置正确,所有这些步骤将确保您的图像数据保留在 GPU 上,而不是从 GPU 传输到 CPU,然后返回 GPU 进行显示。

    好消息是这一切都在 Apple https://developer.apple.com/library/archive/samplecode/AVCamPhotoFilter/Introduction/Intro.html#//apple_ref/doc/uid/TP40017556 的 AVCamPhotoFilter 示例代码中进行了演示。 。特别请参阅 RosyCIRenderer 类及其父类(super class) FilterRenderer

    关于ios - 如何在 iOS 中将 Vignette CIFilter 应用到实时摄像头源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53898780/

    相关文章:

    ios - Swift3中如何根据内容自动改变UICollectionView Cell的高度?

    ios - 有没有办法在运行时读取应用程序的崩溃日志

    ios - 如何使用 `AVCapturesession` 中的 `didOutputSampleBuffer` 播放音频缓冲区

    ios - 使用AV Foundation时捕获的图像方向错误

    包装 Core Text/Core Image 的 Objective-C 库?

    ios - 在 Segue 之前添加完成处理程序

    ios - 以编程方式添加 UIPageViewController

    ios - 我想每秒调用 20 次 installTapOnBus :bufferSize:format:block:

    iphone - CIFeature : Is there only Face Detection? 我可以添加行为吗?

    ios - initWithCVPixelBuffer 失败,因为 CVPixelBufferRef 不是非 IOSurface 支持的