有没有办法以编程方式使给定RGB值的颜色变暗?

Alb*_*lby 14 rgb r colors

假设我有像这样的RGB值(例如在R中):

cols <- c("#CDE4F3","#E7F3D3","#F7F0C7","#EFCFE5","#D0D1E7")
Run Code Online (Sandbox Code Playgroud)

有没有办法以编程方式派生另一组颜色,这是前者的黑暗版本?

它不一定是R.

Rol*_*and 15

library(colorspace)

cols <- c("#CDE4F3","#E7F3D3","#F7F0C7","#EFCFE5","#D0D1E7")

cols1 <- readhex(file = textConnection(paste(cols, collapse = "\n")),
                 class = "RGB")
#transform to hue/lightness/saturation colorspace
cols1 <- as(cols1, "HLS")
cols2 <- cols1
#additive decrease of lightness
cols1@coords[, "L"] <- pmax(0, cols1@coords[, "L"] - 0.3)
#multiplicative decrease of lightness
cols2@coords[, "L"] <- cols2@coords[, "L"] * 0.75
#going via rgb seems to work better  
cols1 <- as(cols1, "RGB")
cols1 <- hex(cols1)
cols2 <- as(cols2, "RGB")
cols2 <- hex(cols2)


plot(x = seq_along(cols), y = rep(1, length(cols)), 
     col = cols, pch = 15, ylim = c(0, 4.5), cex = 5,
     xlab = "", ylab = "")
points(x = seq_along(cols), y = rep(2, length(cols)), 
       col = cols1, pch = 16, cex = 5)
points(x = seq_along(cols), y = rep(3, length(cols)), 
       col = cols2, pch = 17, cex = 5)

legend("top",legend = c("original", "additive", "multipl."), 
       pch = 15:17, ncol = 3)
Run Code Online (Sandbox Code Playgroud)

结果情节

  • 现在,colorspace包具有一个内置的函数“ darken()”,可以执行此操作(不过当前不在RGB空间中)。看我的答案。 (2认同)

Cla*_*lke 12

问题是询问是否有任何方式以编程方式使颜色变暗.问题在于有许多不同的方式,它们都会产生不同的结果.您获得的具体结果取决于所使用的特定算法和使用的颜色空间.

R包colorspace现在提供了一个内置功能,通过该darken()功能使颜色变暗.这个函数使用了我们提出的一个新的"组合"颜色空间,它是HLS和HCL之间的混合.(简而言之,在HCL空间中调整L,但通过绕过HLS调整C,同时保持H不变.)

要使用此功能,您需要安装colorspace的当前开发版本:

install.packages("colorspace", repos = "http://R-Forge.R-project.org")
Run Code Online (Sandbox Code Playgroud)

然后,尝试以下方法:

# original colors
cols <- c("#CDE4F3", "#E7F3D3", "#F7F0C7", "#EFCFE5", "#D0D1E7")

# darken 20%
cols_d2 <- darken(cols, 0.2)

# darken 40%
cols_d4 <- darken(cols, 0.4)

# plot
pal <- function(col, border = "light gray") {
  n <- length(col)
  plot(0, 0, type="n", xlim = c(0, 1), ylim = c(0, 1), axes = FALSE,
       xlab = "", ylab = "")
  rect(0:(n-1)/n, 0, 1:n/n, 1, col = col, border = border)
}

par(mfrow = c(3, 1), mar = c(1, 0, 2, 0))
pal(cols); mtext("original")
pal(cols_d2); mtext("20% darker")
pal(cols_d4); mtext("40% darker")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

您可以尝试使用几种不同的颜色空间和其他调整选项,但默认情况下应该适用于大多数情况.

要查看变暗在不同颜色空间中的效果,请考虑当我们在HCL或HLS中使相同颜色变暗时会发生什么:

在此输入图像描述

HCL变暗的颜色看起来很灰,而且HLS变暗的颜色看起来过于明亮和多彩.但是,根据您的具体应用,您可能需要其中一种结果.


Gre*_*gor 6

HSV价值调整

这似乎比我第一次采用Munsell颜色(下图)更好.它仍然有点乱窜(可能是因为我正在混合使用行和列指定颜色的包以及是否采用矩阵),但它有效:

cols.hsv = rgb2hsv(cols.rgb)
# adjust the "value" down to 80% of it's previous level
cols.hsv["v", ] = cols.hsv["v", ] * 0.8

cols.darker = cols
for (i in seq_along(cols)) {
    cols.darker[i] = hsv(cols.hsv[1, i], cols.hsv[2, i], cols.hsv[3, i])
}

par(mfrow = c(1, 2))
scales::show_col(cols)
scales::show_col(cols.darker)
Run Code Online (Sandbox Code Playgroud)

孟塞尔

我之前没有使用过这个munsell包,所以我可能会把它变得比它需要的更复杂,但它有一个darker"将Munsell颜色的值减少1"的功能.

困难的部分是转换.就像我所知,我们需要将你的十六进制颜色变为我们必须通过RGB的Munsell颜色.

cols <- c("#CDE4F3","#E7F3D3","#F7F0C7","#EFCFE5","#D0D1E7")
cols.rgb = col2rgb(cols)

library(munsell)
# munsell expects rgb colors in rows, not columns, and expects the
# values to be between 0 and 1, not 0 and 255
cols.m = rgb2mnsl(t(cols.rgb) / rowSums(t(cols.rgb)))

# make darker
darker.m = darker(cols.m)
# at least converting back to hex is one step!
darker.hex = mnsl2hex(darker.m)


# view the results
par(mfrow = c(2, 1))
scales::show_col(cols)
scales::show_col(darker.hex)
Run Code Online (Sandbox Code Playgroud)

总的来说,我对此解决方案并不感到兴奋.它使颜色暗,我没有看到在darker功能中调整它的方法.


Ren*_*rez 5

就在这里.

你必须指明你要去的东西变暗或变浅.

这是一个用JavaScript完成的函数:https://css-tricks.com/snippets/javascript/lighten-darken-color/

function LightenDarkenColor(col, amt) {
    var usePound = false;
    if (col[0] == "#") {
        col = col.slice(1);
        usePound = true;
    }
    var num = parseInt(col,16);
    var r = (num >> 16) + amt;
    if (r > 255) {
      r = 255;
    }else if  (r < 0){ 
      r = 0;
    }
    var b = ((num >> 8) & 0x00FF) + amt;
    if (b > 255) {
      b = 255;
    }else if  (b < 0) {
      b = 0;
    }
    var g = (num & 0x0000FF) + amt;
    if (g > 255) {
      g = 255;
    }else if (g < 0) {
      g = 0;
    }
    return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}
Run Code Online (Sandbox Code Playgroud)

希望它有所帮助,干杯.


Rom*_* B. 5

实际上,您可以使用基本图形轻松地做到这一点colorRampPalette()

只需使用您的初始颜色和黑色进行渐变,将其渐变为100,然后选择所需的“深多少”即可(1 =初始,100 =黑色)。

我用一个简洁的小函数来实现这个功能:

darker.col = function(color, how.much = 30){
  colorRampPalette(c(color, "black"))(100)[how.much]
}

plot(1:100, rep(1, 100), pch=16, cex=5, col=darker.col("royalblue", 1:100))
Run Code Online (Sandbox Code Playgroud)