Is there a way to programmatically darken a color based on RGB values?

Say I have RGB values ​​similar to this (e.g. in R):

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

Is there a way to programmatically get another set of colors, which is a darkened version of the first?

It does not have to be R.

+6
source share
5 answers
 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) 

resulting plot

+12
source

Yes there is.

You will need to indicate how dark or lighter you are.

Here is the function executed in 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); } 

Hope this helps, Greetings.

+5
source

HSV value adjustment

This seems a lot better than my first hit with Munsell flowers (below). It still works a bit (possibly because I mix packages that define colors in rows and columns and take matrices or not), but it works:

 cols.hsv = rgb2hsv(cols.rgb) # adjust the "value" down to 80% of it 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) 

Mansell

I haven't used the munsell package munsell , so I could make it more complicated than it should be, but it has a darker function that "Decreases Munsell's color value by 1."

The hard part is conversions. As far as I can tell, we need to get your colors in the hexes for Munsell colors, which we need to go through RGB.

 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) 

In general, I am not happy with this decision. This made the colors much darker, and I see no way to adjust it in the darker function.

+5
source

The question asks if there is a way to programmatically darken the colors. The problem is that there are many different ways, and they all give different results. The specific result you get depends on the particular algorithm used and the color space used.

The R colorspace now provides a built-in function to darken colors using the darken() function. This feature uses the new “combined” color space we have encountered, a combination between HLS and HCL. (In short, configures L in the HCL space, but tunes C by taking a traversal through HLS, keeping constant H).

To use this function, you need to install the current version of the color space:

 install.packages("colorspace", repos = "http://R-Forge.R-project.org") 

Then try the following:

 # 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") 

enter image description here

There are several different color spaces and other settings that you can try, but by default this should work in most cases.

To see the effect of darkening in different color spaces, think about what happens when we darken the same colors in HCL or HLS:

enter image description here

The darkened HCL colors appear rather gray, and the darkened HLS colors appear too bright and colorful. However, depending on your specific application, you may need one of these results.

+5
source

This is not very good code. munsell package might be friendlier

 library(colorspace) cols <- c("#CDE4F3","#E7F3D3","#F7F0C7","#EFCFE5","#D0D1E7") lab = as(hex2RGB(cols),"LAB") lab@coords [,1] = lab@coords [,1] *0.3 # cols1 = hex(as(lab,"RGB")) cols1 
+4
source

Source: https://habr.com/ru/post/987146/


All Articles