How to use AVCapturePhotoOutput

Pranav Wadhwa picture Pranav Wadhwa · Jun 16, 2016 · Viewed 43k times · Source

I have been working on using a custom camera, and I recently upgraded to Xcode 8 beta along with Swift 3. I originally had this:

var stillImageOutput: AVCaptureStillImageOutput?

However, I am now getting the warning:

'AVCaptureStillImageOutput' was deprecated in iOS 10.0: Use AVCapturePhotoOutput instead

As this is fairly new, I have not seen much information on this. Here is my current code:

var captureSession: AVCaptureSession?
var stillImageOutput: AVCaptureStillImageOutput?
var previewLayer: AVCaptureVideoPreviewLayer?

func clickPicture() {

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

        videoConnection.videoOrientation = .portrait
        stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) -> Void in

            if sampleBuffer != nil {

                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                let dataProvider = CGDataProvider(data: imageData!)
                let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)

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

            }

        })

    }

}

I have tried to look at AVCapturePhotoCaptureDelegate, but I am not quite sure how to use it. Does anybody know how to use this? Thanks.

Answer

BilalReffas picture BilalReffas · Jul 3, 2016

Updated to Swift 4 Hi it's really easy to use AVCapturePhotoOutput.

You need the AVCapturePhotoCaptureDelegate which returns the CMSampleBuffer.

You can get as well a preview image if you tell the AVCapturePhotoSettings the previewFormat

    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 photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto 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) {
              print("image: \(UIImage(data: dataImage)?.size)") // Your Image
            }   
        }
    }

For more information visit https://developer.apple.com/reference/AVFoundation/AVCapturePhotoOutput

Note: You have to add the AVCapturePhotoOutput to the AVCaptureSession before taking the picture. So something like: session.addOutput(output), and then: output.capturePhoto(with:settings, delegate:self) Thanks @BigHeadCreations