菜鸟教程小白 发表于 2022-12-13 16:05:12

ios - 如何将 Vignette CIFilter 应用于 iOS 中的实时摄像机源?


                                            <p><p>在尝试将简单的晕影滤镜应用于 iPhone6 的原始摄像头馈送时,在 Metal 和 Core Image 的帮助下,我发现在 <code>MTKView</code>MTKView 中处理和渲染的帧之间存在很多延迟</code></p>

<p>我遵循的方法是(MetalViewController.swift):</p>

<ol>
<li>使用 <code>AVCaptureVideoDataOutputSampleBufferDelegate</code></li> 获取原始相机输出
<li>转换<code>CMSampleBuffer</code> > <code>CVPixelBuffer</code> > <code>CGImage</code> </li>
<li>用这个 <code>CGImage</code> 创建一个 <code>MTLTexture</code>。 </li>
</ol>

<p>点数2 和 3 在名为 <code>fillMTLTextureToStoreTheImageData</code></p> 的方法内

<ol start="4">
<li>将 <code>CIFilter</code> 应用到从 <code>MTKViewDelegate</code> 中的 <code>MTLTexture</code> 获取的 <code>CIImage</code> </li>
</ol>

<pre class="lang-swift prettyprint-override"><code>    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()
            }
      }
    }
</code></pre>

<p>性能完全不是苹果在这个文档中提到的:<a href="https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html#//apple_ref/doc/uid/TP30001185-CH3-TPXREF101" rel="noreferrer noopener nofollow">https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html#//apple_ref/doc/uid/TP30001185-CH3-TPXREF101</a> </p>

<p>我错过了什么吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您的第 2 步太慢了,无法支持实时渲染...而且您似乎遗漏了几个步骤。出于您的目的,您通常会:</p>

<p>设置:</p>

<ol>
<li>创建一个 <code>CVPixelBuffer</code> 池 - 使用 <code>CVPixelBufferPoolCreate</code> </li>
<li>使用 <code>CVMetalTextureCacheCreate</code></li> 创建金属纹理池
</ol>

<p>对于每一帧:</p>

<ol 开始=“3”>
<li>转换 <code>CMSampleBuffer</code> > <code>CVPixelBuffer</code> > <code>CIImage</code></li>
<li>通过过滤器管道传递 <code>CIImage</code></li>
<li>将输出图像渲染到步骤 1 中创建的池中的 <code>CVPixelBuffer</code></li>
<li>使用 <code>CVMetalTextureCacheCreateTextureFromImage</code> 使用过滤后的 CVPixelBuffer 创建金属纹理</li>
</ol>

<p>如果设置正确,所有这些步骤将确保您的图像数据保留在 GPU 上,而不是从 GPU 传输到 CPU 再返回 GPU 进行显示。 </p>

<p>好消息是所有这些都在 Apple <a href="https://developer.apple.com/library/archive/samplecode/AVCamPhotoFilter/Introduction/Intro.html#//apple_ref/doc/uid/TP40017556" rel="noreferrer noopener nofollow">https://developer.apple.com/library/archive/samplecode/AVCamPhotoFilter/Introduction/Intro.html#//apple_ref/doc/uid/TP40017556</a> 的 AVCamPhotoFilter 示例代码中进行了演示.尤其参见 <code>RosyCIRenderer</code> 类及其父类(super class) <code>FilterRenderer</code>。 </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何将 Vignette CIFilter 应用于 iOS 中的实时摄像机源?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/53898780/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/53898780/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何将 Vignette CIFilter 应用于 iOS 中的实时摄像机源?