3

I'm trying to capture RAW files with AVFoundation. However I'm getting empty array in __availableRawPhotoPixelFormatTypes

Here is my snippet

if self._photoOutput == nil {
    self._photoOutput = AVCapturePhotoOutput()
    print(self._photoOutput!.__availableRawPhotoPixelFormatTypes)
}

And the output is empty array []

What may cause this?

Jay Patel
  • 2,642
  • 2
  • 18
  • 40
s1ddok
  • 4,615
  • 1
  • 18
  • 31

2 Answers2

9

Here are three things that will cause the availableRawPhotoPixelFormatTypes array to be empty:

  1. You are reading the availableRawPhotoPixelFormatTypes property before adding your _photoOutput to an AVCaptureSession with a video source.

  2. You are using the dual camera input. If so, you can't capture RAW images.

  3. You are using the front camera. If so, you can't capture RAW images.

Here is some modified sample code from an excellent Apple guide (see link below). I have copied from several places and updated it slightly for brevity, simplicity and better overview:

let session = AVCaptureSession()
let photoOutput = AVCapturePhotoOutput()

private func configureSession() {
    // Get camera device.
    guard let videoCaptureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
        print("Unable to get camera device.")
        return
    }
    // Create a capture input.
    guard let videoInput = try? AVCaptureDeviceInput(device: videoCaptureDevice) else {
        print("Unable to obtain video input for default camera.")
        return
    }

    // Make sure inputs and output can be added to session.
    guard session.canAddInput(videoInput) else { return }
    guard session.canAddOutput(photoOutput) else { return }

    // Configure the session.
    session.beginConfiguration()
    session.sessionPreset = .photo
    session.addInput(videoInput)
    // availableRawPhotoPixelFormatTypes is empty.
    session.addOutput(photoOutput)
    // availableRawPhotoPixelFormatTypes should not be empty.
    session.commitConfiguration()
}

private func capturePhoto() {
    // Photo settings for RAW capture.
    let rawFormatType = kCVPixelFormatType_14Bayer_RGGB
    // At this point the array should not be empty (session has been configured).
    guard photoOutput.availableRawPhotoPixelFormatTypes.contains(NSNumber(value: rawFormatType).uint32Value) else {
        print("No available RAW pixel formats")
        return
    }

    let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: rawFormatType)
    photoOutput.capturePhoto(with: photoSettings, delegate: self)
}

// MARK: - AVCapturePhotoCaptureDelegate methods

func photoOutput(_ output: AVCapturePhotoOutput,
                 didFinishProcessingRawPhoto rawSampleBuffer: CMSampleBuffer?,
                 previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
                 resolvedSettings: AVCaptureResolvedPhotoSettings,
                 bracketSettings: AVCaptureBracketedStillImageSettings?,
                 error: Error?) {
    guard error == nil, let rawSampleBuffer = rawSampleBuffer else {
        print("Error capturing RAW photo:\(error)")
        return
    }
    // Do something with the rawSampleBuffer.
}

Apple's Photo Capture Guide: https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/PhotoCaptureGuide/index.html

The availableRawPhotoPixelFormatTypes property: https://developer.apple.com/documentation/avfoundation/avcapturephotooutput/1778628-availablerawphotopixelformattype)

iPhone camera capabilities: https://developer.apple.com/library/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Cameras/Cameras.html

Thomas
  • 91
  • 4
2

One supplyment to @Thomas's answer:

If you change AVCaptureDevice.activeFormat, AVCaptureSession.sessionPreset will be set to inputPriority automatically. In such situation, availableRawPhotoPixelFormatTypes will be empty too.

Papillon
  • 317
  • 2
  • 10
  • 1
    yes, this answer is right. my solution is to set `session.sessionPresset` to `.photo` again, will work – krosshj Jan 04 '21 at 05:58
  • This is a big hole in apples documentation. I could not understand why the availableRawPhotoPixelFormatTypes kept showing as having no records. Thank you. – lyndon hughey Apr 19 '21 at 15:56