首页 > 解决方案 > SVG 十进制颜色值(0 到 1)如何转换为(0 到 255)颜色值?

问题描述

以下代码清楚地表明,十进制颜色值 (0,1) 不会线性转换为离散值 (0,255)。如果它们是,0,5 将转换为大约 128,但事实并非如此。相反,它转换为 187 左右。

<svg height="100%" width="100%" viewbox="0 0 100 100">
  <defs>
    <filter id="coltrans">
      <feComponentTransfer in="SourceGraphic">
        <feFuncG type="discrete" tableValues="0 1"/>
        <feFuncB type="discrete" tableValues="0 1"/>
      </feComponentTransfer>
    </filter>
  </defs>
  <lineargradient id="0to1gradient">
    <stop offest="0" stop-color="rgb(255, 255, 255)"/>
    <stop offset="1" stop-color="rgb(255,0,0)"/>
  </lineargradient>
  <rect filter="url(#coltrans)" x="0" y="0" width="100" height="50" fill="url(#0to1gradient)" stroke="blue"/>
  <rect x="0" y="50" width="100" height="50" fill="url(#0to1gradient)" stroke="blue"/>
</svg>

在下方的矩形中,颜色从白色线性渐变为红色。上面的矩形具有相同的颜色过渡,只是它被过滤,因此绿色和蓝色十进制颜色值向上或向下舍入到最近的点(0 或 1)。

标签: svg

解决方案


SVG 中的大多数颜色操作都是在sRGB颜色空间中完成的。但是,出于视觉质量的原因,过滤器操作(默认情况下)在线性RGB颜色空间中执行。任何输入图像都被转换为 lineaRGB,过滤器基元被应用,然后过滤器的输出被转换回 sRGB。

有关更多详细信息,请阅读sRGB 维基百科文章SVG 规范

但它基本上归结为 sRGB 是 RGB 的伽马调整版本。这最初是为了补偿旧 CRT 显示器的响应。为了以大约一半的亮度显示像素,您必须向屏幕发送 187 而不是 128。

整体伽马因子约为2.2。

所以为了(大致)从线性RGB转换为sRGB,将输入值提高到(1 / 2.2)的幂

0.5 ^ (1/2.2) = 0.7297

0.7297 * 256 ~= 187

推荐阅读