首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVCapturePhotoOutput未提供预览缓冲区

AVCapturePhotoOutput未提供预览缓冲区
EN

Stack Overflow用户
提问于 2017-05-30 02:56:06
回答 1查看 1.1K关注 0票数 2

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

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

下面是我如何设置捕获的:

代码语言:javascript
复制
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)中:

代码语言:javascript
复制
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。第二次和第二次,我只收到photoSampleBufferpreviewPhotoSampleBuffer = nil,但当我检查resolvedSettings.previewDimensions时,我得到:CMVideoDimensions(width: 160, height: 120)

如果我通过重新配置捕获会话来切换摄像头(从前到后),则随后的第一次捕获是正常的,然后再次没有预览缓冲区。委托回调中的error参数始终为空。

在运行iOS 10.3.1的iPhone 6上测试

EN

回答 1

Stack Overflow用户

发布于 2017-05-30 14:25:11

找到了解决方案,但没有完全理解它是如何导致初始问题的。

我已经将照片捕获委托中预览样本缓冲区的转换更改为通过CIContext对象转换为UIImage。之前,我只是简单地创建了一个CIImage并将其发送到UI (不同的线程),似乎CIImage持有对原始缓冲区的引用,而后来进行的UI处理会以某种方式干扰它,从而影响下一次捕获(同样,我不知道为什么)。

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

代码语言:javascript
复制
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)
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44248937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档