2017-05-29 83 views
2

使用AVCapturePhotoOutput设置自定义摄像头。 配置AVCapturePhotoOutput以提供除主JPEG缓冲区之外的预览缓冲区(缩略图)。AVCapturePhotoOutput不提供预览缓冲区

问题是我只接收预览缓冲区一次(第一次捕捉),然后从第二次接收零(主photoSampleBuffer总是正确接收)。

下面是我设置捕获:

func capturePhoto() { 

    guard let videoPreviewLayerOrientation = deviceOrientation.videoOrientation else { return } 

    sessionQueue.async { 
     if let photoOutputConnection = self.photoOutput.connection(withMediaType: AVMediaTypeVideo) { 
      photoOutputConnection.videoOrientation = videoPreviewLayerOrientation 
     } 

     // each photo captured requires a brand new setting object and capture delegate 
     let photoSettings = AVCapturePhotoSettings() 

     // Capture a JPEG photo with flash set to auto and high resolution photo enabled. 
     photoSettings.isHighResolutionPhotoEnabled = true 

     //configure to receive a preview image (thumbnail) 
     if let previewPixelType = photoSettings.availablePreviewPhotoPixelFormatTypes.first { 
      let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String : previewPixelType, 
           kCVPixelBufferWidthKey as String : NSNumber(value: 160), 
           kCVPixelBufferHeightKey as String : NSNumber(value: 160)] 
      photoSettings.previewPhotoFormat = previewFormat 
     } 

     // TODO: photoSettings.flashMode = .auto 

     // Use a separate object for the photo capture delegate to isolate each capture life cycle. 
     let photoCaptureDelegate = PhotoCaptureDelegate(with: photoSettings, willCapturePhotoAnimation: { [unowned self] in 
      // show shutter animation 
      self.shutterAnimation() 
      }, completed: { [unowned self] (photoCaptureDelegate, photoData, previewThumbnail) in 

       self.captureCompleted(photoCaptureDelegate: photoCaptureDelegate, data: photoData, thumbnail: previewThumbnail) 
      } 
     ) 
     // The Photo Output keeps a weak reference to the photo capture delegate so we store it in an array 
     // to maintain a strong reference to this object until the capture is completed. 
     self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = photoCaptureDelegate 
     self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate) 
    } 
} 

在我PhotoCaptureDelegate(实现AVCapturePhotoCaptureDelegate):

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

    if let photoBuffer = photoSampleBuffer { 
     photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoBuffer, previewPhotoSampleBuffer: nil) 
    } 


    if let previewBuffer = previewPhotoSampleBuffer { 
     if let pixelBuffer = CMSampleBufferGetImageBuffer(previewBuffer) { 
      photoThumbnail = CIImage(cvPixelBuffer: pixelBuffer) 
     } 

    } 
} 

发生什么事是我第一次拍摄我收到两个photoSampleBuffer & previewPhotoSampleBuffer。第2次和我只收到photoSampleBufferpreviewPhotoSampleBuffer = nil虽然当我检查resolvedSettings.previewDimensions我得到: CMVideoDimensions(width: 160, height: 120)

如果我通过重新配置捕获会话第一次捕捉之后是确定,然后再次没有预览切换摄像头(前后)缓冲。委托回调中的参数error始终为零。

在测试了iPhone 6运行iOS 10.3.1

回答

0

找到什么解决方案,但不完全了解它是如何使最初的问题。

我已经改变了我的照片捕获委托中的预览示例缓冲区的转换,以通过CIContext对象转换为UIImage。事先我简单地创建了一个CIImage并将其发送到UI(不同的线程),并且似乎CIImage拥有对原始缓冲区的引用以及稍后用它进行UI处理,以某种方式影响下一次捕获(再次,不明白为什么)。

新代码通过cgImage创建图像的新位图副本,然后将其发送到UI - >因此在原始缓冲区上不进行处理。

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

    if let photoBuffer = photoSampleBuffer { 
     photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoBuffer, previewPhotoSampleBuffer: nil) 
    } 

    let previewWidth = Int(resolvedSettings.previewDimensions.width) 
    let previewHeight = Int(resolvedSettings.previewDimensions.height) 

    if let previewBuffer = previewPhotoSampleBuffer { 
     if let imageBuffer = CMSampleBufferGetImageBuffer(previewBuffer) { 
      let ciImagePreview = CIImage(cvImageBuffer: imageBuffer) 
      let context = CIContext() 
      if let cgImagePreview = context.createCGImage(ciImagePreview, from: CGRect(x: 0, y: 0, width:previewWidth , height:previewHeight)) { 
       photoThumbnail = UIImage(cgImage: cgImagePreview) 
      } 
     } 
    } 
}