小编典典

如何使用Swift将过滤器应用于视频实时

swift

是否可以将过滤器应用于 AVLayer* 并将其添加为 addSublayer 以进行 查看
?我想使用Swift改变颜色并为摄像机的视频添加一些噪点,但我不知道该怎么做。
*

我认为,可以像这样添加 filterLayerPreviewLayer

self.view.layer.addSublayer(previewLayer)
self.view.layer.addSublayer(filterLayer)

这可能可以使用我的自定义滤镜创建视频,但是我认为,可以更有效地使用 AVComposition

所以我需要知道:

  1. 将滤镜实时应用于摄像机视频输出的最简单方法是什么?
  2. 可以合并 AVCaptureVideoPreviewLayerCALayer 吗?

谢谢你的每一个建议。


阅读 242

收藏
2020-07-07

共1个答案

小编典典

还有另一种选择,使用AVCaptureSession创建CIImage实例,您可以对其应用CIFilter(具有从模糊到颜色校正到VFX的负载)。

这是一个使用ComicBook效果的示例。简而言之,创建一个AVCaptureSession:

let captureSession = AVCaptureSession()
captureSession.sessionPreset = AVCaptureSessionPresetPhoto

创建一个AVCaptureDevice代表相机,在这里设置后置相机:

let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

然后创建设备的具体实现,并将其附加到会话。在Swift 2中,实例化AVCaptureDeviceInput可能会引发错误,因此我们需要捕获以下错误:

 do
{
    let input = try AVCaptureDeviceInput(device: backCamera)

    captureSession.addInput(input)
}
catch
{
    print("can't access camera")
    return
}

现在,这里有个“陷阱”:尽管我们实际上并没有使用AVCaptureVideoPreviewLayer,但是它需要使示例委托正常工作,因此我们创建了其中之一:

// although we don't use this, it's required to get captureOutput invoked
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

view.layer.addSublayer(previewLayer)

接下来,我们创建一个视频输出AVCaptureVideoDataOutput,我们将使用它来访问视频提要:

let videoOutput = AVCaptureVideoDataOutput()

确保自我实现AVCaptureVideoDataOutputSampleBufferDelegate,我们可以在视频输出上设置样本缓冲区委托:

 videoOutput.setSampleBufferDelegate(self, 
    queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL))

然后将视频输出附加到捕获会话:

 captureSession.addOutput(videoOutput)

…最后,我们开始捕获会话:

captureSession.startRunning()

因为我们已经设置了委托,所以将在每次捕获帧时调用captureOutput。captureOutput传递了一个CMSampleBuffer类型的样本缓冲区,它只需要两行代码即可将该数据转换为CIImage以便Core
Image处理:

let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)

…,然后将图像数据传递到我们的漫画书效果,该效果又用于填充图像视图:

let comicEffect = CIFilter(name: "CIComicEffect")

comicEffect!.setValue(cameraImage, forKey: kCIInputImageKey)

let filteredImage = UIImage(CIImage: comicEffect!.valueForKey(kCIOutputImageKey) as! CIImage!)

dispatch_async(dispatch_get_main_queue())
{
    self.imageView.image = filteredImage
}

我的GitHub存储库中提供了此项目源代码

2020-07-07