使用自定义相机拍照Swift 3

5

在 Swift 2.3 中,我使用以下代码来在自定义相机中拍照:

 func didPressTakePhoto(){

        if let videoConnection = stillImageOutput!.connection(withMediaType: AVMediaTypeVideo) {

            stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
                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)


                    self.captureImageView.image = image
                }
            })

    }
}

但是他的代码行:

stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { (sampleBuffer, error) -> Void in

显示了这个错误:

类型“AVCapturePhotoOutput”的值没有成员“captureStillImageAsynchronouslyFromConnection”

我尝试解决我的问题,但是我总是遇到越来越多的错误,这就是为什么我发布原始代码的原因。

有人知道如何让我的代码再次工作吗?

谢谢。

3个回答

7

您可以在Swift 3中像这样使用AVCapturePhotoOutput:

您需要AVCapturePhotoCaptureDelegate,它返回CMSampleBuffer

如果您告诉AVCapturePhotoSettings预览格式,您也可以得到预览图像。

class CameraCaptureOutput: NSObject, AVCapturePhotoCaptureDelegate {

    let cameraOutput = AVCapturePhotoOutput()

    func capturePhoto() {

      let settings = AVCapturePhotoSettings()
            let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first!
            let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,
                                 kCVPixelBufferWidthKey as String: 160,
                                 kCVPixelBufferHeightKey as String: 160,
                                 ]
            settings.previewPhotoFormat = previewFormat
            self.cameraOutput.capturePhoto(with: settings, delegate: self)

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

        if let error = error {
            print(error.localizedDescription)
        }

        if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer, let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {
          print(image: UIImage(data: dataImage).size)
        } else {

        }
    }
}

谢谢,你帮了我很多 :) - 0ndre_
1
我正在使用Swift 3,在 print(image: UIIMage...) 行上,我收到一个错误 Argument labels (image:) do not match any available overloads. - noblerare

4
感谢Sharpkits,我找到了解决方案(以下代码适用于我):
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {

        if let error = error {
            print(error.localizedDescription)
        }

        if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer,
            let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {

            let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: nil)
            let dataProvider = CGDataProvider(data: imageData as! CFData)

            let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.absoluteColorimetric)


            let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right)

            let cropedImage = self.cropToSquare(image: image)

            let newImage = self.scaleImageWith(cropedImage, and: CGSize(width: 600, height: 600))

            print(UIScreen.main.bounds.width)


            self.tempImageView.image = newImage
            self.tempImageView.isHidden = false


        } else {

        }
    }

2

好的代码,感谢您提供帮助和示例。

为了让像我这样思维较慢的人更明确,当你在takePhoto (或者其他你命名的方法)里调用self.cameraOutput.capturePhoto(with: settings, delegate: self)时,capture(_ ...etc)方法会在幕后被调用。

您永远不会直接调用捕获方法。它会自动完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接