How to save JPEG/RAW image data to camera roll in iOS 11, can’t access processed image data

Ask A Question

Login To post a question

I’m attempting to write a photoapp that can take both RAW and JPEG images and save them to the camera roll. The functions jpegPhotoDataRepresentation and dngPhotoDataRepresentation seem to be the key to all examples I’ve found, however both of these are deprecated in iOS 11 and the function for saving after “capturePhoto” is now

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

The main example I’ve been able to find of a working RAW iOS11 app is this:
which works, however it only shoots RAW and saving is clumsy because it’s not on the camera roll.

I’ve changed my photo settings to allow for both raw and processed capture with this line

photoSettings = AVCapturePhotoSettings(rawPixelFormatType: availableRawFormat.uint32Value, processedFormat: [AVVideoCodecKey : AVVideoCodecType.jpeg])

But once I’ve actually captured the photo I have no idea how to access the processedFormat data. fileDataRepresentation seems to be the only way to access the dng stuff, but there’s no way to get at the jpeg separately? The code I’ve found from Apple pre-iOS11 suggests to use PHPhotoLibrary and add a resource, but this requires a data representation which I’m unable to access other than as a dng file, which when saved to the library is just white because the library is not able to handle RAW files. Here’s my photoOutput code in case it helps.

 func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

    let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyyMMddHHmmss"
    formatter.locale = Locale.init(identifier: "en_US_POSIX")
    let filePath =  dir.appending(String(format: "/%@.dng", formatter.string(from: Date())))
    let dngFileURL = URL(fileURLWithPath: filePath)

    let dngData = photo.fileDataRepresentation()!
    do {
        try dngData.write(to: dngFileURL, options: [])
    } catch {
        print("Unable to write DNG file.")

    PHPhotoLibrary.shared().performChanges( {
        let creationRequest = PHAssetCreationRequest.forAsset()
        let creationOptions = PHAssetResourceCreationOptions()
        creationOptions.shouldMoveFile = true

        //dngData is the problem, this should be the jpeg representation
        creationRequest.addResource(with: .photo, data: dngData, options: nil)
        //This line works fine, the associated file is the correct RAW file, but the jpeg preview is garbage
        creationRequest.addResource(with: .alternatePhoto, fileURL: dngFileURL, options: creationOptions)

    }, completionHandler: nil)


For more info please click here

Have a question or need a custom quote?