首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将CIImage保存到P3颜色空间完整的照片中?

如何将CIImage保存到P3颜色空间完整的照片中?
EN

Stack Overflow用户
提问于 2017-11-09 11:33:52
回答 1查看 1.7K关注 0票数 4

我正在构建一个相机应用程序,它以BGRA格式捕捉一张照片,并在将其保存到Photos应用程序之前在其上应用核心图像过滤器。在iPhone 7 Plus上,输入照片位于显示P3颜色空间中,但输出位于sRGB颜色空间中:

我怎样才能防止这种情况发生?

这是我的密码:

代码语言:javascript
复制
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.

这些指纹:

代码语言:javascript
复制
Optional(<CGColorSpace 0x1c40a8a60> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Display P3))

(在我的实际代码中,我向CIImage应用了一个筛选器,它创建了另一个CIImage,并将其保存下来。但是即使使用原始的CIImage,我也可以重现这个问题,所以我已经消除了过滤器。)

如何将核心图像过滤器应用于P3图像,并将其保存为P3映像,而不是sRGB?

备注:

(1)这是在iPhone 7 Plus上运行iOS 11的。

(2)我使用的是宽幅相机,而不是远程、双或正面。

(3)如果我要求AVFoundation给我一个JPEG编码的图像,而不是BGRA,并且保存它而不涉及核心图像,那么这个问题不会发生,- the颜色空间不会减少到sRGB。

(4)我尝试使用kCIImageColorSpace,但没有什么不同:

代码语言:javascript
复制
let p3 = CGColorSpace(name: CGColorSpace.displayP3)!
let ciImage = CIImage(
    cvImageBuffer: pixelBuffer,
    options:[kCIImageProperties: metadata,
             kCIImageColorSpace: p3])

(5)在创建kCIContextOutputColorSpace时,除了上面的内容外,我还尝试使用CIContext作为参数,但同样没有什么区别。

(6)接收数据并将其保存到PHPhotoLibrary的代码并不是问题,因为它在上面(2)的情况下工作。

代码语言:javascript
复制
let context = CIContext(options: [kCIContextOutputColorSpace: CGColorSpace.p3])

如何将核心图像过滤器应用于P3图像,并将其保存为P3映像,而不是sRGB?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-03 05:33:03

我也遇到过同样的问题,我认为这可能是context.jpegRepresentation(.)的一个bug。

我在使用ImageIO创建JPEG数据方面取得了更大的成功,如下面的createJPEGData函数所示。例如:

代码语言:javascript
复制
let eaglContext = EAGLContext(api: .openGLES2)
let options = [kCIContextWorkingColorSpace: CGColorSpace(name: CGColorSpace.extendedSRGB)!, 
               kCIContextOutputPremultiplied: true, 
               kCIContextUseSoftwareRenderer: false] as [String : Any]

let ciContext = CIContext(eaglContext: eaglContext, options: options)

let colorSpace = CGColorSpace(name: CGColorSpace.displayP3)!
guard let imageData = createJPEGData(from: image, 
                                     jpegQuality: 0.9,                           
                                     outputColorSpace: colorSpace,
                                     context: ciContext) else {
      return
}

PHPhotoLibrary.shared().performChanges({ () -> Void in
    let creationRequest = PHAssetCreationRequest.forAsset()
    creationRequest.addResource(with: .photo,
                                data: imageData,
                                options: nil)
}, completionHandler: { (success: Bool, error : Error?) -> Void in
    // handle errors, etc
})


func createJPEGData(from image: CIImage,
                    jpegQuality: Float,
                    outputColorSpace: CGColorSpace,
                    context: CIContext) -> Data? {

    let jpegData: CFMutableData =  CFDataCreateMutable(nil, 0)

    if let destination = CGImageDestinationCreateWithData(jpegData, kUTTypeJPEG, 1, nil) {
        if let cgImage = context.createCGImage(image,
                                               from: image.extent,
                                               format: kCIFormatRGBA8,
                                               colorSpace: outputColorSpace) {
            CGImageDestinationAddImage(destination, cgImage, image.properties as CFDictionary?)
            if CGImageDestinationFinalize(destination) {
                return jpegData as Data
            }
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47200791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档