使用AVFoundation捕获静止图像

时间:2017-01-29 19:17:10

标签: swift uiimageview avfoundation

我目前正在创建一个简单的应用程序,它使用AVFoundation将视频流式传输到UIImageView

为实现这一目标,我创建了AVCaptureSession()AVCaptureSessionPreset()

的实例
let input = try AVCaptureDeviceInput(device: device)
                print(input)
                if (captureSession.canAddInput(input)) {
                    captureSession.addInput(input)

                    if (captureSession.canAddOutput(sessionOutput)) {
                        captureSession.addOutput(sessionOutput)
                        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                        previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait

                        cameraView.layer.addSublayer(previewLayer)
                        captureSession.startRunning()
  

cameraView引用UIImageView插座。

我现在想要实现一种从AVCaptureSession捕获静态图像的方法。

如果这是一种更有效的方式,请更正我,但我打算额外UIImageView将静止图像放在保存视频的UIImageView之上?

我创建了一个带动作的按钮:

@IBAction func takePhoto(_sender: Any) {
    // functionality to obtain still image 
}

我的问题是,我不确定如何从捕获会话中实际获取静态图像并使用它填充新的UIImageView

在查看Stack上发布的信息/问题后,大部分解决方案都是使用:

captureStillImageAsynchronouslyFromConnection

我不确定它是否仅仅是Swift 3.0,但是xCode没有识别出这个功能。

有人可以告诉我如何在点击按钮时实际获得获取和显示静止图像的结果。

Here是我完整代码的链接,可以更好地了解我的程序。

感谢大家提前花时间阅读我的问题,如果我错过了一些相关数据,请随时告诉我。

1 个答案:

答案 0 :(得分:2)

如果您的目标是iOS 10或更高版本。 captureStillImageAsynchronously(from:completionHandler:)AVCaptureStillImageOutput一起被弃用。

根据文档

  

在iOS 10.0中不推荐使用AVCaptureStillImageOutput类   不支持更新的相机捕捉功能,如RAW图像输出,   实时照片或宽色域。在iOS 10.0及更高版本中,使用   而是AVCapturePhotoOutput类。 (AVCaptureStillImageOutput   在macOS 10.12中仍然支持class。)

根据您的代码,您已使用AVCapturePhotoOutput。因此,请按照以下步骤从会话中拍摄照片。同样可以在Apple documentation中找到。

  1. 创建AVCapturePhotoOutput对象。使用其属性确定支持的捕获设置并启用某些功能(例如,是否捕获实时照片)。
  2. 创建并配置AVCapturePhotoSettings对象,以选择特定捕获的功能和设置(例如,是否启用图像稳定或闪存)。
  3. 通过将照片设置对象传递给capturePhoto(使用:delegate :)方法以及实现AVCapturePhotoCaptureDelegate协议的委托对象来捕获图像。然后,照片捕获输出会呼叫您的代理人在捕获过程中通知您重大事件。
  4. 您已经在执行第1步和第2步。因此,请在代码中添加此行

    @IBAction func takePhoto(_sender: Any) {
            print("Taking Photo")
            sessionOutput.capturePhoto(with: sessionOutputSetting, delegate: self as! AVCapturePhotoCaptureDelegate)
    
        }
    

    并实施AVCapturePhotoCaptureDelegate功能

    optional public func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?)
    

    请注意,此代表可以对拍照进行大量控制。查看文档以获取更多功能。您还需要处理图像数据,这意味着您必须将样本缓冲区转换为UIImage。

    if sampleBuffer != nil {
      let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
      let dataProvider = CGDataProviderCreateWithCFData(imageData)
      let cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, CGColorRenderingIntent.RenderingIntentDefault)
      let image = UIImage(CGImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.Right)
      // ...
      // Add the image to captureImageView here...
    }
    

    请注意,您获得的图像向左旋转,因此我们必须手动向右旋转,以便像图像一样进行预览。

    我可以在之前的SO answer

    中找到更多信息