javascript - style - ¿Cómo verificar si el color hexadecimal es "demasiado negro"?
rgb color generator (7)
Estoy tratando de evaluar la oscuridad del color elegido por un selector de color para ver si es "demasiado negro", y si es así, configúrelo en blanco. Pensé que podría usar los primeros caracteres del valor hexadecimal para lograr esto. Está funcionando, pero está cambiando algunos colores legítimamente "claros" también.
Tengo un código haciendo esto:
if (lightcolor.substring(0,3) == "#00"|| lightcolor.substring(0,3) == "#010"){
lightcolor="#FFFFFF";
color=lightcolor;
}
Debe haber una manera más eficiente con la matemática hexadecimal para saber que un color ha ido más allá de un cierto nivel de oscuridad. Como si fuera lightcolor + "algún valor hexadecimal" <= "algún valor hexadecimal", configúralo en blanco.
He agregado tinyColor, que podría ser útil para esto, pero no estoy seguro.
¡Un manojo!
Aquí hay una distinción importante entre la luminancia y el brillo. La luminancia, al final del día, es una medida de la cantidad de energía que viaja a través de un área determinada e ignora por completo cómo nuestros sistemas perceptivos perciben esa energía. El brillo, por otro lado, es una medida de cómo percibimos esa energía y tiene en cuenta la relación entre la luminancia y nuestro sistema de percepción. (Como un punto de confusión, hay un término llamado luminancia relativa, que parece ser usado como sinónimo de términos de brillo. Me hizo tropezar bien).
Para ser precisos, está buscando "brillo" o "valor" o "relativamente luminancia" como otros han sugerido. Puedes calcular esto de diferentes maneras (¡es ser humano!) http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
- Tome el máximo de R, G y B.
- Tome el promedio del máximo y el mínimo de R, G y B.
- Tome el promedio de los tres.
- Use un promedio ponderado como otros han sugerido aquí.
Debe extraer los tres componentes RGB individualmente y luego usar una fórmula estándar para convertir los valores RGB resultantes en su brillo percibido.
Asumiendo un color de seis caracteres:
var c = c.substring(1); // strip #
var rgb = parseInt(c, 16); // convert rrggbb to decimal
var r = (rgb >> 16) & 0xff; // extract red
var g = (rgb >> 8) & 0xff; // extract green
var b = (rgb >> 0) & 0xff; // extract blue
var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
if (luma < 40) {
// pick a different colour
}
EDITAR
Desde mayo de 2014, tinycolor
ahora tiene una función getBrightness()
, aunque utiliza los factores de ponderación CCIR601 en lugar de los anteriores ITU-R.
Este trabajo con hex por ejemplo #fefefe
function isTooDark(hexcolor){
var r = parseInt(hexcolor.substr(1,2),16);
var g = parseInt(hexcolor.substr(3,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
// Return new color if to dark, else return the original
return (yiq < 40) ? ''#2980b9'' : hexcolor;
}
Puede cambiarlo para devolver true
o false
por cambio
return (yiq < 40) ? ''#2980b9'' : hexcolor;
a
return (yiq < 40);
La biblioteca TinyColor (ya lo mencionó) proporciona varias funciones para inspeccionar y manipular colores, entre ellas:
Devuelve el brillo percibido de un color, de 0 a 255, como se define en las Pautas de accesibilidad del contenido web (Versión 1.0) .
tinycolor("#fff").getBrightness(); // 255
Devuelve un booleano que indica si el brillo percibido del color es claro.
tinycolor("#fff").isLight(); // true tinycolor("#000").isLight(); // false
Devuelve un valor booleano que indica si el brillo percibido del color es oscuro.
tinycolor("#fff").isDark(); // false tinycolor("#000").isDark(); // true
Devuelve la luminancia percibida de un color, de 0 a 1 según lo definido por las Pautas de Accesibilidad para el Contenido Web (Versión 2.0) .
tinycolor("#fff").getLuminance(); // 1
Me doy cuenta de que esta conversación tiene algunos años, pero sigue siendo relevante. Quería agregar que mi equipo estaba teniendo el mismo problema en Java (SWT) y me pareció un poco más preciso:
private Color getFontColor(RGB bgColor) {
Color COLOR_BLACK = new Color(Display.getDefault(), 0, 0, 0);
Color COLOR_WHITE = new Color(Display.getDefault(), 255, 255, 255);
double luminance = Math.sqrt(0.241
* Math.pow(bgColor.red, 2) + 0.691 * Math.pow(bgColor.green, 2) + 0.068
* Math.pow(bgColor.blue, 2));
if (luminance >= 130) {
return COLOR_BLACK;
} else {
return COLOR_WHITE;
}
}
Puedes calcular la luminance :
La luminancia es un indicador de qué tan brillante aparecerá la superficie.
Así que es genial elegir si el texto debe ser blanco o negro.
var getRGB = function(b){
var a;
if(b&&b.constructor==Array&&b.length==3)return b;
if(a=/rgb/(/s*([0-9]{1,3})/s*,/s*([0-9]{1,3})/s*,/s*([0-9]{1,3})/s*/)/.exec(b))return[parseInt(a[1]),parseInt(a[2]),parseInt(a[3])];
if(a=/rgb/(/s*([0-9]+(?:/.[0-9]+)?)/%/s*,/s*([0-9]+(?:/.[0-9]+)?)/%/s*,/s*([0-9]+(?:/.[0-9]+)?)/%/s*/)/.exec(b))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];
if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],
16)];
if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];
return (typeof (colors) != "undefined")?colors[jQuery.trim(b).toLowerCase()]:null
};
var luminance_get = function(color) {
var rgb = getRGB(color);
if (!rgb) return null;
return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
}
El método anterior le permite pasar el color en diferentes formatos, pero el algoritmo está básicamente en luminance_get
.
Cuando lo usé, estaba configurando el color en negro si la luminancia era mayor que 180
, de lo contrario, en blanco.
Una posible solución sería convertir su color de RGB a HSB . HSB significa hue, saturación y brillo (también conocido como HSV, donde V es para valor). Entonces tienes solo un parámetro para verificar: brillo.