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

时间:2015-09-03 14:38:39

标签: ios swift avfoundation calayer video-capture

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

我想,可以像这样添加 filterLayer previewLayer

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

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

所以我需要知道:

  1. 将滤镜实时应用于相机视频输出的最简单方法是什么?
  2. 是否可以合并 AVCaptureVideoPreviewLayer CALayer
  3. 感谢您的每一个建议..

2 个答案:

答案 0 :(得分:23)

还有另一种选择,使用AVCaptureSession创建CIImage实例,您可以将CIFilters应用于其中(其中有加载,从模糊到颜色校正到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,我们将用它来访问视频Feed:

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
}

我有source code for this project available in my GitHub repo here

答案 1 :(得分:0)

如果您使用的是AVPlayerViewController,则可以设置view的{​​{1}}的compositingFilter属性:

layer

See here for the compositing filter options you can use。例如“ multiplyBlendMode”,“ screenBlendMode”等。

playerController.view.layer.compositingFilter = "multiplyBlendMode" 中执行此操作的示例:

UIViewController

对于class ViewController : UIViewController{ override func viewDidLoad() { //load a movie called my_movie.mp4 that's in your xcode project let path = Bundle.main.path(forResource: "my_movie", ofType:"mp4") let player = AVPlayer(url: URL(fileURLWithPath: path!)) //make a movie player and set the filter let playerController = AVPlayerViewController() playerController.player = player playerController.view.layer.compositingFilter = "multiplyBlendMode" //add the player view controller to this view controller self.addChild(playerController) view.addSubview(playerController.view) playerController.didMove(toParent: self) //play the movie player.play() } } ,请确保将.mp4文件添加到Xcode项目中的“构建阶段”>“复制捆绑包资源”中。或在导入文件时选中“添加到目标”框。

相关问题