3

I want to build an iOS 10 app that lets you shoot a RAW (.dng) image, edit it, and then saved the edited .dng file to the camera roll. By combining code from Apple's 2016 "AVCamManual" and "RawExpose" sample apps, I've gotten to the point where I have a CIFilter containing the RAW image along with the edits.

However, I can't figure out how to save the resulting CIImage to the camera roll as a .dng file. Is this possible?

Kalpesh Dusane
  • 1,477
  • 3
  • 20
  • 27
Trevor Alyn
  • 687
  • 2
  • 8
  • 20

4 Answers4

5

Unfortunately DNG isn't supported as an output format in Apple's ImageIO framework. See the output of CGImageDestinationCopyTypeIdentifiers() for a list of supported output types:

(
    "public.jpeg",
    "public.png",
    "com.compuserve.gif",
    "public.tiff",
    "public.jpeg-2000",
    "com.microsoft.ico",
    "com.microsoft.bmp",
    "com.apple.icns",
    "com.adobe.photoshop-image",
    "com.adobe.pdf",
    "com.truevision.tga-image",
    "com.sgi.sgi-image",
    "com.ilm.openexr-image",
    "public.pbm",
    "public.pvr",
    "org.khronos.astc",
    "org.khronos.ktx",
    "com.microsoft.dds",
    "com.apple.rjpeg"
)
TyR
  • 718
  • 4
  • 9
  • Saw this right after I filed a radar about the RAW output support in ImageI/O framework. Absence of the support makes it impossible to even edit the EXIF and Geotag data of RAW, which I was trying to implement. – Xiao Xiao Jul 07 '17 at 02:40
5

A RAW file is "raw" output direct from a camera sensor, so the only way to get it is directly from a camera. Once you've processed a RAW file, what you have is by definition no longer "raw", so you can't go back to RAW.

To extend the metaphor presented at WWDC where they introduced RAW photography... a RAW file is like the ingredients for a cake. When you use Core Image to create a viewable image from the RAW file, you're baking the cake. (And as noted, there are many different ways to bake a cake from the same ingredients, corresponding to the possible options for processing RAW.) But you can't un-bake a cake — there's no going back to original ingredients, much less a way that somehow preserves the result of your processing.

Thus, the only way to store an image processed from a RAW original is to save the processed image in a bitmap image format. (Use JPEG if you don't mind lossy compression, PNG or TIFF if you need lossless, etc.)

If you're writing the results of an edit to PHPhotoLibrary, use JPEG (high quality / less compressed if you prefer), and Photos will store your edit as a derived result, allowing the user to revert to the RAW original. You can also describe the set of filters you applied in PHAdjustmentData saved with your edit — with adjustment data, another instance of your app (or Photos app extension) can reconstruct the edit using the original RAW data plus the filter settings you save, then allow a user to alter the filter parameters to create a different processed image.


Note: There is a version of the DNG format called Linear DNG that supports non-RAW (or "not quite RAW") images, but it's rather rare in practice, and Apple's imaging stack doesn't support it.

rickster
  • 124,678
  • 26
  • 272
  • 326
  • Kinda what I figured. Apps like Lightroom must just bypass Core Image and do the RAW file manipulation directly to the file using their own methods. That's a good tip about writing the image as JPEG to PHPhotoLibrary, thanks! – Trevor Alyn Sep 21 '16 at 16:06
  • 1
    Lightroom etc can't un-bake the cake either. When they take a RAW file and save DNG, what they're doing is saving the original RAW data (which may be in a camera-specific file format like Canon or Nikon RAW), plus metadata describing your RAW processing settings, along with (typically) a JPEG preview of the processing results, into a common file format that can hold all of those things. The original RAW data remains unchanged, it's just repackaged into a different file that also contains other data. – rickster Sep 21 '16 at 18:56
2

This answer comes late, but it may help others with the problem. This is how I saved a raw photo to the camera roll as a .dng file.

Just to note, I captured the photo using the camera with AVFoundation.

 import Photos
 import AVFoundation 

 //reading in the photo data in as a data object
 let photoData = AVCapturePhotoOutput.dngPhotoDataRepresentation(forRawSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)

 // put it into a temporary file
 let temporaryDNGFileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("temp.dng")!     
 try! photoData?.write(to: temporaryDNGFileURL)

 // get access to photo library
 PHPhotoLibrary.requestAuthorization { status in
            if status == .authorized {

                // Perform changes to the library
                PHPhotoLibrary.shared().performChanges({

                    let options = PHAssetResourceCreationOptions()
                    options.shouldMoveFile = true

                    //Write Raw:
                    PHAssetCreationRequest.forAsset().addResource(with: .photo, fileURL: temporaryDNGFileURL, options: options)

                    }, completionHandler: { success, error in
                        if let error = error { print(error) }
                })

            }
            else { print("cant access photo album") }
}

Hope it helps.

0

The only way to get DNG data as of the writing of this response (iOS 10.1) is:

AVCapturePhotoOutput.dngPhotoDataRepresentation(forRawSampleBuffer: CMSampleBuffer, previewPhotoSampleBuffer: CMSampleBuffer?) 

Noting the OP refers to Core Image. As mentioned by rickster, CI works on processed image data, therefore only offers processed image results (JPEG, TIFF):

CIContext.writeJPEGRepresentation(of:to:colorSpace:options:)
CIContext.writeTIFFRepresentation(of:to:format:colorSpace:options:)
Bobjt
  • 4,040
  • 1
  • 29
  • 29