【发布时间】:2013-12-16 23:24:18
【问题描述】:
这是我的问题:
我正在使用光谱样本进行一些渲染,并希望保存显示结果的图像。我通过 CIE XYZ 颜色匹配函数对我的光谱功率函数进行加权以获得 XYZ 颜色空间结果。我将此 XYZ 颜色元组乘以 this page 给出的矩阵以转换为 sRGB,并将结果钳制为 (0,1)。
为了保存图像,我将转换后的元组缩放 255 并将其转换为字节,然后将数组传递给 libpng 的png_write_image()。当我查看以这种方式渲染的均匀强度、纯色谱时,它看起来是错误的;颜色之间的过渡中有暗带。这可能并不令人惊讶,因为要从 XYZ 转换为 sRGB,矩阵之后的颜色分量 must be raised to 2.4 会相乘(或者如果它们足够小,则进行线性缩放)。但如果我这样做,它看起来更糟!只有在加注到 1/2.2 之后,它才开始看起来正确。看起来,在我没有做任何事情的情况下,解码图像的伽马值约为 2.2,两次。
这是我期望它工作的方式:我将矩阵应用于 XYZ,并且我有一个大致能量线性的 RGB 元组。我将它提高到 2.2,现在有一个感知线性颜色元组。我按原样对这些数字进行编码(从而有效利用文件精度),并在文件中存储一个字段,说明“这些字节已使用 gamma 2.2 编码”。然后在图像加载时,解码系统取消应用编码的伽玛,然后在显示之前应用系统伽玛。 (因此从创作的角度来看,我不必关心观众的系统伽玛是什么)。但我得到的结果表明它不能以这种方式工作。
更糟糕的是,我尝试使用 2.2 和 1/2.2 调用 png_set_gAMA(),但在图像中看不到任何差异。我用png_set_sRGB() 得到了类似的结果(我相信这应该迫使伽马为1/2.2)。
关于我应该如何转换我的颜色值,或者 PNG 如何处理伽马和颜色空间,我一定有一些倒退或不理解的东西。将其分解为几个明确的问题:
- 我希望传递给
write_png()的字节值的颜色空间是什么? - 我必须对 libpng 进行哪些调用(如果有),以指定传递字节的色彩空间和 gamma,以确保正确显示?为什么他们会失败?
- png 文件中的 gamma 字段与我应用于传递的颜色通道值(如果有)的指数有什么关系?
- 如果希望我在发送图像数据之前反转 gamma 曲线(我对此表示怀疑,但现在似乎有必要),那么该反转是否应该包括 sRGB 曲线的线性部分?
此外,我发现“白点”在 XYZ 和 sRGB 之间的转换中很重要。我不清楚上面给出的站点中的矩阵是否包括对 D65 的重整化(它与 Wikipedia 的矩阵不匹配) - 甚至何时需要进行这种转换。我发现的大多数文献都掩盖了细节。维基文章中没有提到转换中的另一个步骤,还是会自动处理?
【问题讨论】:
标签: graphics colors png libpng color-space