在 JavaScript 中将十六进制颜色值转换为 RGB

问题描述 投票:0回答:1

我有这个代码:

let hexInt = parseInt(hex, 16);

let r = (hexInt >> 16) & 255;
let g = (hexInt >> 8) & 255;
let b = hexInt & 255;

我知道一个十六进制数字需要 4 位来指定它的值。因此,6 个十六进制数字意味着 24 位,其中每个颜色分量有 8 位。

F0 is 11110000
0F is 00001111
F0 in decimal is 240
0F in decimal is 15

我无法理解的是 parseInt(hex, 16) 将我们的十六进制字符串转换为十进制值,而它们没有这样直接的转换。

84 in binary is 1010100
48 in binary is 110000

对于十进制数,位数根据数字的大小而变化。

十六进制数不会出现这种情况。

我的代码中的数字

hexInt
现在是十进制数。它的大小取决于十六进制值。因此,用于表示它的字节数将取决于十六进制值。

因此,我们不能总是做16位和8位右移来隔离颜色分量。

为什么上面的代码可以工作?

我错过了什么?

谢谢。

javascript binary hex decimal rgb
1个回答
0
投票

简短版本:

我们可以使用 16 和 8 位移位来隔离组件,因为 设计的十六进制颜色始终每个组件使用 8 位。分量的大小并不重要。如果你想要红色并且它的值为

00
那么你必须在提取红色值之前将8个“零”移动16位(到蓝色的位置)。

示例:

color   : #00F7A5
comp    : RR = 00, GG = F7, BB = A5
Mask    : FF0000 (mask to keep first two hex digits from RRGGBB )
Shift   :  >> 0  , >> 8   , >> 16 (makes new output of 0000RR)
Mask    : 0000FF or just FF (mask to keep last two hex digits from 0000RR )

相同结果的简化版本是:

(myColorInt >> 16 ) & 0xFF)

更长的答案...

关于十六进制表示法:

“我知道十六进制数字需要 4 位来指定其值。
因此,6 个十六进制数字意味着 24 位,其中每个颜色分量获得 8 位。”

十六进制数字至少需要1位来指定其值(即使该值是

0
)。
十六进制颜色始终需要每个组件8位

(对于:红色、绿色或蓝色)。

0F这样的颜色分量似乎只使用4位,但它实际上是8位

,只是前面4位设置为零,但它们仍然计入该分量的8位总数。

有 8 位计数,因为每个组件都被“合并”到一个 R/G/B 插槽中。一个槽最初容纳 8 个零。

为什么 24 位是 6 个十六进制数字?

在十六进制颜色中,您有 3 个值(对于 RGB),每个值都由 2 个十六进制数字组成。这是因为每个 R/G/B 值都是 8 位。基本上它们都是一个

byte 值。单个字节有 8 位长,但它本身可以分为两半,每部分 4 位,每个单元称为“半字节”。一个字节是 2 个十六进制数字,代表 8 位的两个半字节。 半字节(4 位)不计算在内。只有一个完整字节(作为一个 8 位或两个 4 位半字节)是组件的值。

关于使用

>>

进行位移位和使用 &

 运算符进行屏蔽:



我不明白的是

parseInt(hex, 16)
转换我们的十六进制 字符串转换为十进制值,但它们没有这么简单 转换。

84 in binary is 1010100
48 in binary is 110000

对于十进制数,位数根据 数字的大小。
[十进制数]的大小取决于十六进制值。
因此,用于表示它的

bytes

位数将取决于 十六进制值。

因此,我们不能总是做16位和8位右移来隔离 颜色成分。

let r = (hexInt >> 16) & 255; let g = (hexInt >> 8) & 255; let b = hexInt & 255;

为什么上面的代码可以工作?

对于使用任意数量的位的情况,您的逻辑是正确的。

然而,RGB 表示法是一个系统(或标准?),其中每个组件都被分装到一个 8 位插槽中。规则是必须进行位移才能提取任何红色、绿色或蓝色值。

因此,在十六进制颜色中,我们可以而且必须始终使用 16 或 8 位移位来隔离 R/G/B 分量。

考虑 24 位整数

0xRRGGBB

,它实际上是 3 个字节

[RR] [GG] [BB]

byte offset :   02 01 00
component   :   RR GG BB
bit-pos     :   16 08 00 //# how far from zero (to isolate)
Mask & FF00 :   00 FF 00 //# mask [r,g,b] as [-,g,-] using "& 0x00FF00"
Result      :   00 GG 00 //# result output of mask (notice is now "GG00")
Result >> 8 :   00 00 GG //# shift bits torward zero ( 0000[00GG00] --> 00[0000GG]00 )
Result & FF :         GG //# mask is "& 0x0000FF" for isolated Green value eg: 230


© www.soinside.com 2019 - 2024. All rights reserved.