浏览器如何处理rgb(百分比);对于奇怪的数字
这与 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想我无论如何都找到了 Firefox 的解决方案,我想你可能会喜欢后续:
查看源代码我发现了一个文件:
nsCSSParser.cpp
对于每个 rgb 百分比,它执行以下操作:
在与其他 2 个组件和 alpha 组合之前
频道
寻找有关 NSToIntRound 的更多详细信息:
NSToIntRound 是 NS_lroundf 的包装函数
这个函数实际上非常聪明,花了我一段时间来破译(我真的没有很好的 C++ 背景)。
假设 x 为正数
x 加上 0.5f,然后转换为整数
如果 x 的小数部分小于 0.5,则加 0.5 不会改变整数,并且小数部分会被截断,
否则整数值会增加 1并且小数部分被截断。
我同意你们大多数人的说法,这似乎是一个与浏览器相关的问题,所以我将做进一步的工作对其他浏览器的研究。
非常感谢!
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:
before it is combined with the other 2 components and an alpha
channel
Looking for more detail on NSToIntRound:
NSToIntRound is a wrapper function for NS_lroundf
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.
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!
不,不止于此,因为精度不限于一位小数。例如,这是有效的语法:
这样做的原因是,虽然每个组件 8 位很常见(因此是十六进制代码),但较新的硬件支持每个组件 10 或 12 位;更宽的色域色彩空间需要更多的位来避免条带。
这种位深度不可知论也是较新的 CSS 颜色规范使用 0 到 1 浮点范围的原因。
尽管如此,CSS 对象模型仍然要求颜色值以每个组件 8 位进行序列化。这种情况将会改变,但 CSS 工作组仍在讨论更高精度的替代方案。因此,目前浏览器不允许您获得每个精度分量超过 8 位。
如果要将浮点或百分比形式转换为十六进制(或 0 - 255 整数),正确的方法是舍入。下限或上限不会在范围的顶部或底部均匀地指定值。
No, more than that, because the precision is not limited to one decimal place. For example, this is valid syntax:
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.