UIImage created from MTKView results in color/opacity differences

前端 未结 3 1230
-上瘾入骨i
-上瘾入骨i 2021-02-10 06:30

When I capture the contents of an MTKView into a UIImage, the resulting image looks qualitatively different, as shown below:

The code I use to generate the UIIm

相关标签:
3条回答
  • 2021-02-10 07:13
    let context = CIContext()
    let texture = metalView.currentDrawable!.texture
    let cImg = CIImage(mtlTexture: texture, options: nil)!
    let cgImg = context.createCGImage(cImg, from: cImg.extent)!
    let uiImg = UIImage(cgImage: cgImg)
    
    0 讨论(0)
  • 2021-02-10 07:16

    Your CGColorSpace is .sRGB but your renderPipelineDescriptor's pixelFormat is .bgra8Unorm. Try changing that line to:

    renderPipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat.bgra8Unorm_srgb
    
    0 讨论(0)
  • 2021-02-10 07:33

    I've seen this issue in a couple of posts, but no clear answer. Here is what I've found:

    For starters,

    renderPipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat.bgra8Unorm
    

    should really just be set to the MTKView's native pixel format

    renderPipelineDescriptor.colorAttachments[0].pixelFormat = self.colorPixelFormat
    

    Secondly, when I set the CIImage's options:

    let kciOptions = [kCIContextWorkingColorSpace: CGColorSpace(name: CGColorSpace.sRGB)!,
                             kCIContextOutputPremultiplied: true,
                             kCIContextUseSoftwareRenderer: false] as [String : Any]
    

    It didn't matter what I set kCIContextWorkingColorSpace to, I never saw any visual difference regardless of what I used. The property I really needed to set is called KCIImageColorSpace. So the updated kciOptions looks like:

    let kciOptions = [kCIImageColorSpace: CGColorSpaceCreateDeviceRGB(),
                          kCIContextOutputPremultiplied: true,
                          kCIContextUseSoftwareRenderer: false] as [String : Any]
    

    In a similar way of using the view's native pixel format, calling CGColorSpaceCreateDeviceRGB() creates an RGB colorspace that is specific to the device being used.

    0 讨论(0)
提交回复
热议问题