SWIFT 3:使用AVCapturePhotoOutput捕获照片(需要另一组眼睛来查看代码,为什么这不起作用?)

问题描述:

我有一个自定义相机,将AVCapturePhotoCaptureDelegate添加到类中,以下代码捕获一个静止图像图片:SWIFT 3:使用AVCapturePhotoOutput捕获照片(需要另一组眼睛来查看代码,为什么这不起作用?)

奥特莱斯,变量和常量

@IBOutlet weak var cameraPreview: UIView! 
@IBOutlet wear var takePhotoPreview: UIImageView! 

private var cameraView: AVCaptureVideoPreviewLayer! 
private var camera: AVCaptureDevice! 
private var cameraInput: AVCaptureDeviceInput! 
private var cameraOutput: AVCapturePhotoOutput! 
private var photoSampleBuffer: CMSampleBuffer? 
private var previewPhotoSampleBuffer: CMSampleBuffer? 
private var photoData: Data? = nil 

private let cameraSession = AVCaptureSession() 
private photoOutput = AVCapturePhotoOutput() 

设置摄像机会议

private func createCamera() { 
    cameraSession.beginConfiguration() 
    cameraSession.sessionPreset = AVCaptureSessionPresetPhoto 
    cameraSession.automaticallyConfiguresCaptureDeviceForWideColor = true 

    // Add Camera Input 
    if let defaultCamera = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .back).devices { 
     camera = defaultCamera.first 
     do { 
      let cameraInput = try AVCaptureDeviceInput(device: camera) 
      if cameraSession.canAddInput(cameraInput) { 
       cameraSession.addInput(cameraInput) 
       print("Camera input added to the session") 
      } 
     } catch { print("Could not add camera input to the camera session") } 
    } 

    // Add Camera View Input 
    if let cameraView = AVCaptureVideoPreviewLayer(session: cameraSession) { 
     cameraView.frame = cameraPreview.bounds 
     cameraView.videoGravity = AVLayerVideoGravityResizeAspectFill 
     cameraView.cornerRadius = 12.0 
     cameraPreview.layer.addSublayer(cameraView) 
     print("Camera view created for the camera session") 
    } else { print("Could not create camera preview") } 

    // Add Photo Output 
    let cameraPhotoOutput = AVCapturePhotoOutput() 
    if cameraSession.canAddOutput(cameraPhotoOutput) { 
     cameraSession.addOutput(cameraPhotoOutput) 
     cameraPhotoOutput.isHighResolutionCaptureEnabled = true 
     print("Camera output added to the camera session") 
    } else { 
     print("Could not add camera photo output to the camera session") 
     cameraSession.commitConfiguration() 
     return 
    } 

    cameraSession.commitConfiguration() 

    cameraSession.startRunning() 
} 

CaptureButton

@IBOutlet weak var cameraShutter: UIButton! 
@IBAction func cameraShutter(_ sender: UIButton) { 
    let photoSettings = AVCapturePhotoSettings() 
    photoSettings.flashMode = .on 
    photoSettings.isHighResolutionPhotoEnabled = true 
    photoSettings.isAutoStillImageStabilizationEnabled = true 
    if photoSettings.availablePreviewPhotoPixelFormatTypes.count > 0 { 
     photoSettings.previewPhotoFormat = [ kCVPixelBufferPixelFormatTypeKey as String : photoSettings.availablePreviewPhotoPixelFormatTypes.first!] 
    } 
    cameraPhotoOutput.capturePhoto(with: photoSettings, delegate: self) 
} 

的iOS观测相机功能

func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { 
    if let photoSampleBuffer = photoSampleBuffer { 
     photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) 
     let photoDataProvider = CGDataProvider(data: photoData as! CFData) 
     let cgImagePhotoRef = CGImage(jpegDataProviderSource: photoDataProvider!, decode: nil, shouldInterpolate: true, intent: .absoluteColorimetric) 
     let newPhoto = UIImage(cgImage: cgImagePhotoRef!, scale: 1.0, orientation: UIImageOrientation.right) 
     self.takePhotoPreview.image = newPhoto 
     self.takePhotoPreview.isHidden = false 
    } 
     else { 
     print("Error capturing photo: \(error)") 
     return 
    } 
} 

好了,所以这里的交易 - 我把一个断点cameraPhotoOutput.capturePhoto(with: photoSettings, delegate: self)并在步入线路收到以下错误消息:

错误消息

致命错误:意外地发现零而展开的可选值 [运行细节]致命错误:意外地发现零而展开的可选值

上面的代码是直接从苹果公司的示例文档“AVCam”沿着输入来自SO Q & As(link,link,和其他重复这些答案的其他人)。我的最终目标是捕捉图像,并立即将图像和用户推送到新的ViewController进行编辑/发布/保存;然而,我正在使用一个UIImageView来确认捕捉......这首先不起作用。

那么,这是怎么回事呢?这让我坚持了几天。

夫特3,XCODE 8

+0

我要指出,捕获会话中显示视频预览饲料工作得很好,零个问题 - 这是引起头痛的拍摄照片的动作。 CameraViewController以模态方式呈现在tabBarController上。 – brolly

+0

您是否真的在像iPad这样的实际设备上进行测试? –

+0

@ElTomato是的,iPhone 7+ – brolly

好的,理解了它。 El Tomato与问题儿童走在了正确的轨道上,但这不是正确的处方。我的createCamera()功能设置为private,这当然会使内容在其身体外不可见。所以当我调用正确的AVCapturePhotoOutput()时,调用capturePhoto()调用执行时抛出所描述错误的缓冲区源不存在。

因此,这意味着该行:

cameraPhotoOutput.capturePhoto(with: photoSettings, delegate: self)

是正确的,但它只是不正确的设置成执行。为了确认正确执行我...

  • 改变了我的private let photoOutput = AVCapturePhotoOutput()不断
  • private let cameraPhotoOutput = AVCapturePhotoOutput()
  • ,称那是恒定的直接private func createCamera()

这立即执行完美的图像捕捉。

而且更换cameraPhotoOutput,一个AVCapturePhotoOutput(),具有cameraOutput,一个AVCapturePhotoOutput!,被尝试和简单地再现的错误。

如果您有兴趣:cgImage创建过程在func capture(_ : capture...函数中保持不变。在其范围内,我还确定了相机设备的位置,如果是前置相机,则更改图像的方向,并将主照片发送到ReviewViewController上的var photoContent: UIImage?变量。

希望我的心理错误帮助别人:-)

尝试改变

cameraPhotoOutput.capturePhoto(with: photoSettings, delegate: self) 

cameraOutput.capturePhoto(with: photoSettings, delegate: self as AVCapturePhotoCaptureDelegate) 
+2

我喝了第二杯啤酒。希望这会起作用。 –

+0

如果要让应用程序在iPad上运行,还需要执行某些操作。 –