How do I save a CIImage to Photos with its P3 color space intact?

I'm building a camera app that captures a photo in the BGRA format, and applies a Core Image filter on it before saving it to the Photos app. On the iPhone 7 Plus, the input photo is in the Display P3 color space, but the output is in the sRGB color space:

How do I prevent this from happening?

Here's my code:

let sampleBuffer: CMSampleBuffer = ...

let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!

let metadata = CMCopyDictionaryOfAttachments(nil, self, kCMAttachmentMode_ShouldPropagate)!

let ciImage = CIImage(cvImageBuffer: pixelBuffer,

options:[kCIImageProperties: metadata])

NSLog("\(ciImage.colorSpace)")



let context = CIContext()

let data = context.jpegRepresentation(of: ciImage,

colorSpace: ciImage.colorSpace!,

options: [:])!

// Save this using PHPhotoLibrary.

This prints:

Optional(<CGColorSpace 0x1c40a8a60> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Display P3))

(In my actual code, I apply a filter to the CIImage, which creates another CIImage, which I save. But I can reproduce this problem even with the original CIImage, so I've eliminated the filter.)

How do I apply a Core Image filter to a P3 image and save it as a P3 image, not sRGB?

Notes:

(1) This is on iPhone 7 Plus running iOS 11.

(2) I'm using the wide camera, not tele, dual or front.

(3) If I ask AVFoundation to give me a JPEG-encoded image rather than BGRA, and save it without involving Core Image, this problem doesn't occur — the color space isn't reduced to sRGB.

(4) I tried using kCIImageColorSpace, but it made no difference:

let p3 = CGColorSpace(name: CGColorSpace.displayP3)!
let ciImage = CIImage( cvImageBuffer: pixelBuffer, options:[kCIImageProperties: metadata, kCIImageColorSpace: p3])

(5) I tried using kCIContextOutputColorSpace in addition to the above, as an argument when creating the CIContext, but it again made no difference.

(6) The code that takes a Data and saves it to PHPhotoLibrary is not the problem, since it works in case (2) above.

let context = CIContext(options: [kCIContextOutputColorSpace: CGColorSpace.p3])

How do I apply a Core Image filter to a P3 image and save it as a P3 image, not sRGB?

Replies

Hi kart,


Have you tried setting the working color space of the context?

context = CIContext(options: [CIContextOption.workingColorSpace: CGColorSpace(name: CGColorSpace.displayP3)!])

Also keep in mind that

CGColorSpace.displayP3
is just the name of the color space, not the
CGColorSpace
object.