用于 HDR 显示的 CIContext 选项

问题描述 投票:0回答:1

我有两个 CIContext 配置了以下选项:

let options1:[CIContextOption:Any] = [CIContextOption.cacheIntermediates: false, CIContextOption.outputColorSpace: NSNull(), CIContextOption.workingColorSpace: NSNull()];

let options2:[CIContextOption:Any] = [CIContextOption.cacheIntermediates: false];

以及配置了 HDR 输出的带有 CAMetalLayer 的 MTKView。

    metalLayer = self.layer as? CAMetalLayer
    
    metalLayer?.wantsExtendedDynamicRangeContent = true
    metalLayer.colorspace = CGColorSpace(name: CGColorSpace.itur_2100_HLG)
    
    colorPixelFormat = .bgr10a2Unorm

当输入位于 BT.2020 像素缓冲区中时,两个上下文选项会产生不同的输出。但我相信输出不应该有所不同。因为第一个选项只是禁用颜色管理。第二个在 sRGB 扩展线性色彩空间中执行中间缓冲区计算,然后将这些缓冲区转换为输出中的 BT.2020 色彩空间。输出是否因为中间步骤丢失信息而不同?

最后,哪个选项在显示 HDR 样本缓冲区时是正确的?

ios core-image metalkit mtkview
1个回答
0
投票

让我先回答您的最后一个问题:是的,这是设置

MTKView
显示 HDR 内容的有效且良好的方法。

剩下的我想分成两个主题:

工作色彩空间

你是对的:设置

CIContextOption.workingColorSpace: NSNull()
时,你实际上禁用了Core Image的自动颜色管理。但是,我只建议在以下情况下这样做:

  • 你知道输入的色彩空间是什么,
  • 您不应用任何内置过滤器(因为它们假设其输入位于 CI 的默认工作色彩空间中),并且
  • 您将输出配置为与输入处于相同的颜色空间。

因此,在您的情况下,如果您不想在管道中应用过滤器,您可能可以通过将工作空间设置为

NSNull()
来禁用颜色匹配。这甚至可以节省一点处理时间,尽管不是很多,因为色彩空间转换相当便宜。

在大多数情况下,我建议不要触及

workingColorSpace
选项,让 CI 决定使用什么。

输出色彩空间

不幸的是,

CIContextOption.outputColorSpace
非常具有误导性。它似乎并没有在几乎所有用例中使用——至少到目前为止我还没有看到任何效果。

那是因为通常你

  • 将输出颜色空间直接传递给
    CIContext
    的渲染 API,如
    createCGImage(_ image:, from fromRect:, format:, colorSpace:)
    ,
  • 或者渲染目标定义颜色空间。

第二点是这里的症结所在。我相信您正在使用

CIRenderDestination
API 渲染到视图中,可能定义如下:

let destination = CIRenderDestination(width: Int(drawableSize.width),
                                      height: Int(drawableSize.height),
                                      pixelFormat: self.colorPixelFormat,
                                      commandBuffer: commandBuffer,
                                      mtlTextureProvider: { () -> MTLTexture in
                                          return currentDrawable.texture
                                      })

这里的问题是

CIRenderDestination
无法自行完全推断目标的颜色空间(通常默认为 sRGB)。这就是为什么你必须明确设置它。

在这里您知道视图期望可绘制纹理包含

itur_2100_HLG
中的像素数据。因此,要么直接设置,要么简单地将其设置为视图的颜色空间:

destination.colorSpace = metalLayer.colorspace

然后 Core Image 将知道在渲染到目标时要转换到哪个颜色空间。

通过此更改,关闭 (

CIContextOption.workingColorSpace: NSNull()
) 和打开颜色管理之间现在应该不再有差异。

© www.soinside.com 2019 - 2024. All rights reserved.