将RGB颜色值转换为十进制数

12

如何将RGB颜色值转换为纯十进制?

我有一个RGB(255,255,255)代表白色
它的十进制等价物是:16777215

我尝试认为它可能只是:

var dec = r*g*b; // but this doesn't work

虽然这并不奏效。

有人知道将RGB(或RGBA)转换为十进制的算法/方程吗?


3
16,777,215是你的RGB(255,255,255)的十六进制版本0x00FFFFFF的十进制等价值。 - Chris O
你打算用这些值做什么?你将把它们提供给哪些软件/函数等? - Nicol Bolas
我有一个Flash应用程序中的颜色值,它们是十进制的,我需要在HTML/CSS中显示它们,并且还需要进行相互转换。 - sazr
6个回答

21

通常情况下,RGB整数会被视为三个不同的字节,最左边(高位)的字节是红色,中间的字节是绿色,最右边(低位)的字节是蓝色。您可以按如下方式检索这些单独字节的值:

var c = 0xff03c0; // 16712640
var components = {
    r: (c & 0xff0000) >> 16, 
    g: (c & 0x00ff00) >> 8, 
    b: (c & 0x0000ff)
};

通过将组成颜色的字节向后移位,您可以从其组件重新创建颜色:

c = (components.r << 16) + (components.g << 8) + (components.b);
在你的情况下,只需将components.r(等等)替换为你实际的变量即可。

12

一个更好的答案(在清晰度方面)是这个:

'Convert RGB to LONG:
 LONG = B * 65536 + G * 256 + R

'Convert LONG to RGB:
 B = LONG \ 65536
 G = (LONG - B * 65536) \ 256
 R = LONG - B * 65536 - G * 256

LONG是您想要生成的长整数(十进制)。很简单吧? 当然,使用位移操作。


1
@DanielA.White可能不这么认为,但我认为这个问题的任何其他答案都没有这个答案清晰明了。即使是我也能理解这个答案。 - John Bingham
1
这只对那些不了解位操作的人来说似乎更容易,就像对于那些不懂法语的人来说,一个糟糕的英语答案似乎比一个好的法语答案更好一样。学习位操作,你将学习到可推广的原则,从长远来看,这将使我的答案更加清晰明了。 - Wayne
1
实际上应该是:LONG = R * 65536 + G * 256 + B(你把B和R搞混了) 请参考https://www.rapidtables.com/web/color/RGB_Color.html - vorwerg-ni

3

我同意使用位移运算符更加清晰,而且可能性能更好。

话虽如此,如果你想得到一个数学答案,由于语言支持的原因(例如在电子表格中执行此操作),取模%和截断(trunc())或向下取整(floor())可以使其变得简单:

当然,假设红色、绿色和蓝色的8位值为0-255:

Original Answer翻译成"最初的回答"

var rgbTotal = red * 65536 + green * 256 + blue;

var R = Math.trunc( rgbTotal / 65536 );
var G = Math.trunc( ( rgbTotal % 65536 ) / 256 );
var B = rgbTotal % 256;
讨论: 指向Sam的答案,RGB值在顺序上几乎总是大端的,特别是在网页、JPEG和PNG中。个人认为最好将红色乘以65536,而不是蓝色,除非你使用的库需要另外处理。 要返回单独的值:
  • R只需除以65536并截断余数。
  • 对于G,我们通过模65536丢弃R,然后通过256除以截断余数(余数即为蓝色)。
  • 对于B,我们取模256,这样就可以处理高位的两个字节了。

对于R和G,数字需要被截断以丢弃余数,这主要是为了得到整数,具体取决于语言。在JavaScript中,Math.trunc()是一种简单的方法,Math.floor()也可以。对于B,这不是必需的,因为它本身就是模数的余数——然而,这也假设我们不需要像来自用户输入的错误检查一样的错误检查,即B的值始终是一个整数0-255。


3
if (color.substr(0, 1) === '#') {
    return color;
}
var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
var red = parseInt(digits[2]);
var green = parseInt(digits[3]);
var blue = parseInt(digits[4]);
var rgb = blue | (green << 8) | (red << 16);
return rgb.toString(10);

1
需要的是 rgb.toString(10)。 - sharon_antony

2
var dec = (b & 0xff) << 16 + (g & 0xff) << 8 + (r & 0xff);

(我认为这是r、g、b值的正确顺序)

更新

我刚刚检查了浏览器应用程序,发现顺序出错了,因此用于浏览器(阅读HTML+CSS+javascript)的正确公式是:

var dec = r << 16 + g << 16 + b;

假设r,g,b的值<= 255。
其他API可能期望r,g,b值的不同顺序。我似乎记得至少有一个API的顺序是相反的(根据我的原始答案),但我现在不确定是哪个API。

你可能是对的关于顺序,如果是这样,那么我的答案就是错误的 :( - Martin James
正确的顺序是针对什么?是针对谁?顺序取决于谁在读取该值。 - Nicol Bolas
@Nicol - 不,正确的顺序取决于API。我不确定Win32 API,但对于基于浏览器的应用程序(我认为这里正在讨论),我相当确定蓝色是高位字节(三个字节中的一个),红色是低位字节。 - Andrew Cooper
如果这些变量只保存单个颜色分量,那么位掩码实际上就没有意义了。 - Wayne
@lwburk - 确实。位掩码的存在是为了安全起见,以防个别变量包含值> 255的情况。如果您想剪辑值而不是掩码(这对某些应用程序可能更合适),也可以执行max(r, 255) - Andrew Cooper
显示剩余5条评论

0

你需要左移 R 16 位,G 左移 8 位,或者两者都移动到 B 中。查看每个值的二进制表示,一切就会变得清晰明了:

R 255 = 11111111B G 255 = 11111111B B 255 = 11111111B

将 R 左移 16 位: 111111110000000000000000 将 G 左移 8 位: 000000001111111100000000

或运算到 B: 111111111111111111111111

转换为十进制数:16777215


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接