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

Dav*_*ora 10 video-capture avfoundation calayer ios swift

是否可以将过滤器应用于AVLayer并将其添加到以addSublayer的形式查看?我想改变颜色,并使用Swift从相机中添加一些噪音,我不知道如何.

我想,可以像这样添加filterLayerpreviewLayer:

self.view.layer.addSublayer(previewLayer)
self.view.layer.addSublayer(filterLayer)
Run Code Online (Sandbox Code Playgroud)

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

所以我需要知道的是:

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

谢谢你的每一个建议..

Sim*_*man 23

还有另一种选择,使用AVCaptureSession创建CIImage的实例,你可以应用CIFilters(其中有负载,从模糊到颜色校正到VFX).

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

let captureSession = AVCaptureSession()
captureSession.sessionPreset = AVCaptureSessionPresetPhoto
Run Code Online (Sandbox Code Playgroud)

创建一个AVCaptureDevice来代表相机,这里我正在设置后置摄像头:

let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
Run Code Online (Sandbox Code Playgroud)

然后创建设备的具体实现并将其附加到会话.在Swift 2中,实例化AVCaptureDeviceInput会抛出错误,所以我们需要捕获:

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

    captureSession.addInput(input)
}
catch
{
    print("can't access camera")
    return
}
Run Code Online (Sandbox Code Playgroud)

现在,这里有点'陷阱':虽然我们实际上并没有使用AVCaptureVideoPreviewLayer,但需要让示例委托工作,所以我们创建其中一个:

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

view.layer.addSublayer(previewLayer)
Run Code Online (Sandbox Code Playgroud)

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

let videoOutput = AVCaptureVideoDataOutput()
Run Code Online (Sandbox Code Playgroud)

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

 videoOutput.setSampleBufferDelegate(self, 
    queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL))
Run Code Online (Sandbox Code Playgroud)

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

 captureSession.addOutput(videoOutput)
Run Code Online (Sandbox Code Playgroud)

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

captureSession.startRunning()
Run Code Online (Sandbox Code Playgroud)

因为我们已经设置了委托,所以每次帧捕获都会调用captureOutput.captureOutput传递一个CMSampleBuffer类型的示例缓冲区,它只需要两行代码就可以将该数据转换为CIImage以供Core Image处理:

let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)
Run Code Online (Sandbox Code Playgroud)

...并且图像数据被传递到我们的漫画书效果,而漫画书效果又用于填充图像视图:

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
}
Run Code Online (Sandbox Code Playgroud)

在这里的GitHub仓库中提供了这个项目源代码.

  • @NinjaDevelopers 你可以,但你必须将缓冲区输出写入一个文件,我认为你可以使用 `AVAssetWriterInputPixelBufferAdaptor` 来做到这一点,请参阅 http://stackoverflow.com/questions/3741323/how-do-i-export- uiimage-array-as-a-电影 (2认同)