浏览器如何处理rgb(百分比); 对于奇怪的数字

Ray*_*Ray 7 css browser hex colors

这与CSS颜色代码有关:

对于十六进制代码,我们可以表示从#000000到#FFFFFF的16,777,216种颜色

根据W3C Specs,有效RGB百分比适合(0.0%至100.0%),基本上为您提供1,003,003,001种颜色组合.(1001 ^ 3)

根据规格:

当色域已知时,应将设备色域外的值剪裁或映射到色域:红色,绿色和蓝色值必须更改为落在设备支持的范围内.用户代理可以执行从一个色域到另一个色域的更高质量的颜色映射.对于典型的CRT监视器,其设备色域与sRGB相同,以下四个规则是等效的:

我怀疑浏览器是否真的可以渲染所有这些值.(但如果他们这样做请告诉我并忽略这篇文章的其余部分)

我假设有一些从rgb(百分比)到十六进制的映射.(但我再也不确定这是如何工作的)

理想情况下,我想找出函数rgb(百分比) - > HEX

如果我不得不猜测它可能是这3个中的一个.

1)舍入到最近的十六进制

2)CEIL到最近的HEX

3)FLOOR到最近的HEX

问题是我需要准确的映射,我不知道在哪里搜索.我的眼睛无法区分那个级别的颜色,但也许有一些聪明的方法来测试这三个中的每一个.

它也可能取决于浏览器.这可以测试吗?

编辑:

Firefox seems to round from empirical testing.
Run Code Online (Sandbox Code Playgroud)

编辑:

我现在正在浏览Firefox的源代码,

nsColor.h
// A color is a 32 bit unsigned integer with four components: R, G, B
// and A.
typedef PRUint32 nscolor;
Run Code Online (Sandbox Code Playgroud)

似乎Fiefox每个R,G和B只有255个值的空间.暗示舍入可能是答案,但也许有些事情是通过alpha通道完成的.

Ray*_*Ray 1

我想我已经找到了 Firefox 的解决方案,我想你可能会喜欢后续内容:

查看源代码,发现一个文件:

nsCSSParser.cpp

对于每个 RGB 百分比,它执行以下操作:

  1. 它需要百分比分量乘以 255.0f
  2. 将其存储在浮点数中
  3. 将其传递到函数 NSToIntRound 中
  4. NSToIntRound 的结果被存储到一个 8 位整数数据类型中,然后与其他 2 个组件和一个 alpha 通道组合

寻找有关 NSToIntRound 的更多详细信息:

nsCoord.h
inline PRInt32 NSToIntRound(float aValue)
{
  return NS_lroundf(aValue);
}
Run Code Online (Sandbox Code Playgroud)

NSToIntRound 是 NS_lroundf 的包装函数

nsMathUtils.h
inline NS_HIDDEN_(PRInt32) NS_lroundf(float x)
{
    return x >= 0.0f ? PRInt32(x + 0.5f) : PRInt32(x - 0.5f);
}
Run Code Online (Sandbox Code Playgroud)

这个函数实际上非常聪明,花了我一段时间来破译(我确实没有很好的C++背景)。

假设 x 为正数

它将 0.5f 添加到 x,然后转换为整数

如果 x 的小数部分小于 0.5,则添加 0.5 不会改变整数,并且小数部分会被截断,

否则,整数值将增加 1,并且小数部分将被截断。

  1. 所以每个分量的百分比首先乘以255.0f
  2. 然后四舍五入并转换为 32 位整数
  3. 然后再次转换为8位整数

我同意你们大多数人的说法,这似乎是一个依赖于浏览器的问题,所以我将对其他浏览器进行进一步的研究。

非常感谢!