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

发布于 2024-12-09 20:28:36 字数 1091 浏览 0 评论 0原文

这与 CSS 颜色代码有关:

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

。根据 W3C 规范,有效 RGB 百分比的范围为(0.0% 到 100.0%),本质上为您提供 1,003,003,001 种颜色组合。 (1001^3)

根据规格:

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

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

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

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

如果我不得不猜测它可能是其中之一。

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

2) CEIL 到最近的十六进制

3) FLOOR 到最近的十六进制

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

它也可能依赖于浏览器。这个可以测试吗?

编辑:

Firefox seems to round from empirical testing.

编辑:

我现在正在查看 Firefox 的源代码,

nsColor.h
// A color is a 32 bit unsigned integer with four components: R, G, B
// and A.
typedef PRUint32 nscolor;

看来 Fiefox 只能为每个 R、G 和 B 提供 255 个值的空间。暗示舍入可能是答案,但也许阿尔法通道正在做一些事情。

This is related to CSS color codes:

For hexcode we can represent 16,777,216 colors from #000000 to #FFFFFF

According to W3C Specs, Valid RGB percentages fit in a range from (0.0% to 100.0%) essentially giving you 1,003,003,001 color combinations. (1001^3)

According to the specs:

Values outside the device gamut should be clipped or mapped into the gamut when the gamut is
known: the red, green, and blue values must be changed to fall within the range supported by
the device. Users agents may perform higher quality mapping of colors from one gamut to
another. For a typical CRT monitor, whose device gamut is the same as sRGB, the four rules
below are equivalent:

I'm doubtful if browsers actually can render all these values. (but if they do please tell me and ignore the rest of this post)

Im assuming there's some mapping from rgb(percentage) to hex. (but again Im not really sure how this works)

Ideally I'd like to find out the function rgb(percentage)->HEX

If I had to guess it would probably be one of these 3.

1) Round to the nearest HEX

2) CEIL to the nearest HEX

3) FLOOR to the nearest HEX

Problem is I need to be accurate on the mapping and I have no idea where to search.
There's no way my eyes can differentiate color at that level, but maybe there's some clever way to test each of these 3.

It might also be browser dependent. Can this be tested?

EDIT:

Firefox seems to round from empirical testing.

EDIT:

I'm looking through Firefox's source code right now,

nsColor.h
// A color is a 32 bit unsigned integer with four components: R, G, B
// and A.
typedef PRUint32 nscolor;

It seems Fiefox only has room for 255 values for each R,G and B. Hinting that rounding might be the answer, but maybe somethings being done with the alpha channel.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

热风软妹 2024-12-16 20:28:36

我想我无论如何都找到了 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);
}

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);
}

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

假设 x 为正数

x 加上 0.5f,然后转换为整数

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

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

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

我同意你们大多数人的说法,这似乎是一个与浏览器相关的问题,所以我将做进一步的工作对其他浏览器的研究。

非常感谢!

I think I found a solution for Firefox anyways, thought you might like a follow up:

Looking through the source code I found a file:

nsCSSParser.cpp

For each rgb percentages it does the following:

  1. It takes the percentage component multiplies it by 255.0f
  2. Stores it in a float
  3. Passes it into a function NSToIntRound
  4. The result of NSToIntRound is stored into an 8 bit integer datatype,
    before it is combined with the other 2 components and an alpha
    channel

Looking for more detail on NSToIntRound:

nsCoord.h
inline PRInt32 NSToIntRound(float aValue)
{
  return NS_lroundf(aValue);
}

NSToIntRound is a wrapper function for NS_lroundf

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

This function is actually very clever, took me a while to decipher (I don't really have a good C++ background).

Assuming x is positive

It adds 0.5f to x and then casts to an integer

If the fractional part of x was less than 0.5, adding 0.5 won't change the integer and the fractional part is truncated,

Otherwise the integer value is bumped by 1 and the fractional part is truncated.

  1. So each component's percentage is first multiplied by 255.0f
  2. Then Rounded and cast into a 32bit Integer
  3. And then Cast again into an 8 bit Integer

I agree with most of you that say this appears to be a browser dependent issue, so I will do some further research on other browsers.

Thanks a bunch!

胡渣熟男 2024-12-16 20:28:36

根据 W3C 规范,有效 RGB 百分比的范围为(0.0% 到 100.0%),本质上为您提供 1,003,003,001 种颜色组合。 (1001^3)

不,不止于此,因为精度不限于一位小数。例如,这是有效的语法:

rgb(23.456% 78.90123456% 0%)

这样做的原因是,虽然每个组件 8 位很常见(因此是十六进制代码),但较新的硬件支持每个组件 10 或 12 位;更宽的色域色彩空间需要更多的位来避免条带。

这种位深度不可知论也是较新的 CSS 颜色规范使用 0 到 1 浮点范围的原因。

尽管如此,CSS 对象模型仍然要求颜色值以每个组件 8 位进行序列化。这种情况将会改变,但 CSS 工作组仍在讨论更高精度的替代方案。因此,目前浏览器不允许您获得每个精度分量超过 8 位。

如果要将浮点或百分比形式转换为十六进制(或 0 - 255 整数),正确的方法是舍入。下限或上限不会在范围的顶部或底部均匀地指定值。

According to W3C Specs, Valid RGB percentages fit in a range from (0.0% to 100.0%) essentially giving you 1,003,003,001 color combinations. (1001^3)

No, more than that, because the precision is not limited to one decimal place. For example, this is valid syntax:

rgb(23.456% 78.90123456% 0%)

The reason for this is that, while 8 bits per component is common (hence hex codes) newer hardware supports 10 or 12 bits per component; and wider gamut colorspaces need more bits to avoid banding.

This bit-depth agnosticism is also why newer CSS color specifications use a 0 to 1 float range.

Having said which, the CSS Object Model still requires color values to be serialized at 8 bits per component. This is going to change, but the higher-precision replacement is still being discussed in the CSS working group. So for now, browsers don't let you get more than 8 bits per component of precision.

If you are converting a float or percentage form to hex (or to 0 - 255 integer) the correct method is rounding. Floor or ceiling will not spec the values evenly at the top or bottom of the range.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文