使用编程方式使一个十六进制颜色变暗

40

最简单的编程方式是如何将十六进制颜色加深?


我发现这个GitHub Gist对于以编程方式进行颜色转换非常有用-请注意,那里的fraction参数是百分比。因此,我使用输入0.05将颜色加深了5% - https://gist.github.com/martintreurnicht/f6bbb20a43211bc2060e - Gene Bo
这对我有用 - https://dev59.com/QlwY5IYBdhLWcg3wD0LG#33072575 - akshat tailang
10个回答

38

如果你不需要过多的控制,只是想要一种通常较暗的颜色版本,则可以采用以下方法:

col = (col & 0xfefefe) >> 1;

如果颜色值是按通道打包为一个字节(byte)的话,有一个很好的快速方法可以将其减半(显然)。

同样地,使颜色变亮的方法是:

col = (col & 0x7f7f7f) << 1;

有没有办法让它变暗四分之一而不是一半? - mk12
4
更亮的颜色可以用 (col & 0x7f7f7f) << 1 表示,不过对于更复杂的操作最好将 RGB 分量拆分并分别处理。 - cobbal
4
如果你需要得到一个稍微深一点的颜色,可以尝试这个方法:将原始颜色值中的某些位通过位运算清零(& 0x7E7E7E),再将结果右移一位(>> 1),最后将某些位设置为1以达到调暗的效果(| (col & 0x808080))。 - robbrit
9
你能解释一下这里发生了什么吗? - Sisir
2
@Sisir:0xFE在二进制中是11111110。使用它与&运算符,可以将每个颜色字节的最小位(十进制值为1)设置为零。>>运算符将所有内容向下移动一个位置,因此零现在位于价值255点的位置上,而每个颜色的其余部分则位于仅有一半价值的位置上。 - okdewit
显示剩余2条评论

29

将十六进制颜色转换为整数RGB分量:

#FF6600 = rbg(255, 102, 0)

如果你想将颜色变暗5%,那么只需将所有整数值减少5%:

255 - 5% = 242
102 - 5% = 96
0 - 5% = 0

= rbg(242, 96, 0)

转换回十六进制颜色

= #F26000

1
由于相对亮度的原因,这种方法实际上不会很好地工作 - 而HSV比例尺考虑了这一点。仅仅通过同样的量减少所有RGB值,结果颜色看起来会更绿和蓝(因为这些组分似乎比红色更亮)。 - Frerich Raabe
Windows 10 创作者更新版通过将 RGB 数值降低约 45%,使登录屏幕图像变暗。 - js2010

21

一个用javascript实现的函数:

// credits: richard maloney 2006
function getTintedColor(color, v) {
    if (color.length >6) { color= color.substring(1,color.length)}
    var rgb = parseInt(color, 16); 
    var r = Math.abs(((rgb >> 16) & 0xFF)+v); if (r>255) r=r-(r-255);
    var g = Math.abs(((rgb >> 8) & 0xFF)+v); if (g>255) g=g-(g-255);
    var b = Math.abs((rgb & 0xFF)+v); if (b>255) b=b-(b-255);
    r = Number(r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r).toString(16); 
    if (r.length == 1) r = '0' + r;
    g = Number(g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g).toString(16); 
    if (g.length == 1) g = '0' + g;
    b = Number(b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b).toString(16); 
    if (b.length == 1) b = '0' + b;
    return "#" + r + g + b;
} 

示例:

> getTintedColor("ABCEDEF", 10)
> #c6f7f9

1
如果有其他人想要将此代码用于Three.js的THREE.Color - 只需从第一个赋值开始直接使用r、g和b(当您有数字时),并将每个数字除以255,因为RGB值应该在0到1之间。 - poshaughnessy

13

嗯,我没有伪代码可以给你,但我有一个提示。如果你想深化一种颜色并保持它的色调,你应该将那个十六进制值转换成HSB(色相、饱和度、亮度),而不是RGB。这样,你就可以调整亮度而不改变色调,从而使它看起来仍然是同一种颜色。然后,你可以将这个HSB转换回十六进制。


這個程式可以運行,但對於一個簡單的任務而言太過複雜。 - cobbal
1
实际上,我更喜欢这种方法,因为我有更多的控制。请注意,在Android中它是HSV。Color.colorToHSV(col, hsv); - Travis Castillo
这是实现此功能的JavaScript代码:https://gist.github.com/xaphod/ae965011d4864abc4052ebd08c3b795c - xaphod

5
given arg darken_factor # a number from 0 to 1, 0=no change, 1=black
for each byte in rgb_value
    byte = byte * (1 - darken_factor)

3

2

RGB颜色(以十六进制RGB表示法)通过调整阴影、键、亮度或亮度来变暗或变亮。请参见游乐场:colorizer.org


选项1. 将R、G、B值转换为较暗的色调

这个很简单,但容易出错。这里是从每个值的(0,255)范围中减去16个点:

myHex = 0x8c36a9;
darkerHex = myHex - 0x101010;
#  0x7c2699;

如果R、G、B值中有任何一个小于或等于0x0f,则十六进制将下溢。可以使用以下代码解决此问题。

myHex = 0x87f609;
darkenBy = 0x10;
floor = 0x0;

darkerHex = (max((myHex >> 16) - darkenBy, floor) << 16) + \
    (max(((myHex & 0xff00) >> 8) - darkenBy, floor) << 8) + \
    max(((myHex & 0xff) - darkenBy), floor);
# 0x77e600

# substitute `ceiling=0xff;` and `min((myHex ...) + lightenBy, ceiling)` for lightening

选项2. 将R、G、B值缩放以增加黑色

CMYK模型中,关键(黑色)是在(0,1)范围内的R、G、B值的最大值的1减去。

这个很简单,你可以用很少的代码得到很好的结果。您正在通过单个缩放因子重新调整R、G、B值的分布。

将缩放因子表示为2位十六进制数(因此50%将是.5*0x1000x80,1/16将是0x10,10%将向下舍入为0x19)。

#  Assumes integer division ... looking at you python3 >:(

myHex = 0x8c36a9;
keyFactor = 0x10;                   #  Lighten or darken by 6.25%
R = myHex >> 16;                    #  0x8c
G = (myHex & 0xff00) >> 8;          #  0x36
B = myHex & 0xff;                   #  0xa9

darkerHex = ((R-R*keyFactor/0x100) << 16) +  # Darker R
            ((G-G*keyFactor/0x100) << 8) +   # Darker G
            (B-B*keyFactor/0x100);           # Darker B
#  0x84339f

#  substitute `(X+keyFactor-X*keyFactor/0x100)` for lightening 
#  0x9443af

选项三:在保持色调不变的情况下降低亮度或明度

在 RGB 的 HSL 表示中,亮度是 R、G、B 值的最小值和最大值之间的中点。对于 HSV,明度是 R、G、B 值的最大值。

考虑使用您所用语言的内置或外部 RGB/HEX 转 HSL/HSV 转换器。然后调整 L/V 值并转换回 RGB/HSL。你可以像 #1 & #2 一样手动进行转换,但实现可能不会比现有的转换器节省更多时间(见链接中的数学公式)。


2
  • 将十六进制颜色拆分为RGB组件。
  • 将每个组件转换为整数值。
  • 将该整数乘以一个分数,例如0.5,确保结果也是整数。
    • 或者从该整数中减去一定量,确保不低于0。
  • 将结果转换回十六进制。
  • 按RGB顺序连接这些值,并使用。

1

一个十六进制颜色,例如#FCFCFC,由三个表示RGB的对组成。每对的第二部分可以减小以使颜色变暗而不会显著改变颜色。

例如,要使#FCFCFC变暗,请降低C的值以得到#F0F0F0

将每对的第一部分减少一点也会使颜色变暗,但您将开始更改颜色(例如,将绿色变为蓝色)。


1

您应该考虑在L*a*b*颜色空间中加深颜色。以下是使用chroma.js的JavaScript示例:

chroma.hex("#FCFC00").darker(10).hex()  // "#dde000"

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