2017-05-29 86 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) 
      } 
     } 
    } 
}