2017-11-09 32 views
3

BGRA 형식으로 사진을 캡처하는 카메라 앱을 만들고 사진 앱에 저장하기 전에 Core Image 필터를 적용합니다. 아이폰 7 플러스에서 입력 사진은 디스플레이 P3 색 공간에 있지만 출력은 sRGB 색 공간에 :P3 색상 공간이 그대로있는 CIImage를 사진에 저장하려면 어떻게합니까?

enter image description here

어떻게 이런 일이 발생하지 않도록합니까?

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. 

이 인쇄 : 여기

내 코드의

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

(내 실제 코드에서, 내가 저장 다른 CIImage를 생성 CIImage에 필터를 적용하지만. 원래의 CIImage에서도이 문제를 재현 할 수 있으므로 필터가 제거되었습니다.)

어떻게 P3 이미지에 코어 이미지 필터를 적용하고 P3으로 저장합니까? 이미지가 아닌 sRGB?


참고 :

(1)이 아이폰 7 플러스 실행 아이폰 OS에 11

(2)이 넓은 카메라,하지 텔레, 듀얼 또는 전면을 사용하고 있습니다.

(3) AVGRoundation에서 BGRA가 아닌 JPEG 인코딩 이미지를 제공하고 Core Image를 포함하지 않고 저장하면이 문제는 발생하지 않습니다. 색상 공간이 sRGB로 축소되지 않습니다.

(4) 내가 kCIImageColorSpace을 사용했지만, 그 차이되지 :

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

(5) I는 CIContext를 생성 할 때의 인수로서, 상기 이외에 kCIContextOutputColorSpace을 사용했지만,이를 다시 제조 차이 없음.

(6) 데이터를 취하여 PHPhotoLibrary에 저장하는 코드는 위의 경우 (2)에서 작동하므로 문제가되지 않습니다.

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

은 어떻게 P3 이미지에 코어 이미지 필터를 적용하고, P3 이미지,하지의 sRGB로 저장합니까?

답변

0

동일한 문제가 있었는데 context.jpegRepresentation (..)이있는 버그 일 수 있습니다.

아래의 createJPEGData 함수에서와 같이 ImageIO를 사용하여 JPEG 데이터를 만드는 데 성공했습니다. 예 :

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 
      } 
     } 
    } 
}