Reputation: 321
I am trying to find the correct color. For example if I have a dark green color then I need a light green color or if I have a light green color then I need a dark green color. I have a code which tells me if the color is dark or light.
function calcBrightness(red,green,blue) {
return Math.sqrt(
red * red * .299 +
green * green * .587 +
blue * blue * .114);
}
var brightness = calcBrightness(red, green, blue);
var foreColor = (brightness < 130) ? "light" : "green";
I am able to detect if the color is dark or light but how can I get the dark color if the result is light or light color if the foreColor
value is green?
Upvotes: 3
Views: 6888
Reputation: 23541
Getting the lightness can be done with a quick conversion following ITU-R BT.709.
const getLightness = (r,g,b) => 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
const isDark = (r, g, b) => getLightness(r, g, b) < 90;
const isLight = (r, g, b) => getLightness(r, g, b) > 150;
The formula can be found on Wikipedia:
The letter Y refers to relative luminance [...] Y can be calculated for these colorspaces by using the coefficients for the Y component of the transform matrix. For instance, for ITU-R BT.709 and sRGB both of which use the same primaries and whitepoint, relative luminance can be calculated from linear RGB components: first convert the gamma-compressed RGB values to linear RGB, and then
The formula reflects the luminous efficiency function as "green" light is the major component of luminance, responsible for the majority of light perceived by humans, and "blue" light the smallest component.
Demo:
const getLightness = (r, g, b) => 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
const isDark = (r, g, b) => getLightness(r, g, b) < 90;
const isLight = (r, g, b) => getLightness(r, g, b) > 150;
const hexTorgb = (hex) => ['0x' + hex[1] + hex[2] | 0, '0x' + hex[3] + hex[4] | 0, '0x' + hex[5] + hex[6] | 0];
document.querySelector("#colorpicker").onchange = (e) => {
const hex = e.target.value;
const rgb = hexTorgb(hex);
document.body.style.backgroundColor = hex;
document.querySelector("span").textContent = isDark(...rgb) ? "dark" : isLight(...rgb) ? "light" : "";
document.body.style.color = isDark(...rgb) ? "white" : "black";
}
<label for="colorpicker">selet a background color: </label>
<input type="color" id="colorpicker" value="#000">
You choose a <span>light</span> color.
Upvotes: 0
Reputation: 25331
Technically speaking, it's actually better to do light/darkness in the HSL color space.
To save you some hassle, there's some great javascript libraries out there that have all kinds of color manipulation, such as TinyColor.
You don't really define what "light" and "dark" verisons of the colors are, but here's a quick example I threw together using TinyColor: http://jsfiddle.net/cm00kb04/1/
Effectively this is doing:
function findTextColor(backgroundColor) {
var c = tinycolor(backgroundColor);
return c.isDark() ? c.lighten(50) : c.darken(50);
}
You can do various levels of lightening/darkening, as well as find mostReadable()
color among other manipulations.
What will result in the best outcome is going to depend on the context: eg, if this is handling any possible color, if there is a theme it must work with, etc.
Upvotes: 4
Reputation: 2577
From your description, I believe it would require a color-space conversion from RGB to HSL (hue, saturation, lightness), change the lightness value to suit your needs and then convert back the new color to RGB. You can find the code here Wikipedia offers a good explanation on the HSL and HSV/HSB color spaces and their relationship with RGB color space
Upvotes: 1
Reputation: 4591
Convert RGB color to HSL (Hue, Saturation, Lightness) makes the problem much easier.
You can easily adjust the lightness of your color by changing the L
value in HSL.
The algorithm is available here
(from the question Javascript convert HSB/HSV color to RGB accurately)
Upvotes: 3