colors - para - como poner letras de colores
¿Cómo decidir el color de la fuente en blanco o negro dependiendo del color de fondo? (11)
Quiero mostrar algunas imágenes como este ejemplo
El color de relleno se decide por un campo en la base de datos con el color en hexadecimal (por ejemplo: ClaseX -> Color: # 66FFFF). Ahora, quiero mostrar los datos sobre un relleno con el color seleccionado (como en la imagen de arriba), pero necesito saber si el color es oscuro o claro, así que sé si las palabras deben ser blancas o negras. ¿Hay alguna manera? tks
¿Qué tal esto (código de JavaScript)?
/**
* Get color (black/white) depending on bgColor so it would be clearly seen.
* @param bgColor
* @returns {string}
*/
getColorByBgColor(bgColor) {
if (!bgColor) { return ''''; }
return (parseInt(bgColor.replace(''#'', ''''), 16) > 0xffffff / 2) ? ''#000'' : ''#fff'';
}
@SoBiT, estaba viendo tu respuesta, que se ve bien, pero hay un pequeño error. Su función hexToG y hextoB necesitan una edición menor. El último número en substr es la longitud de la cadena, por lo que en este caso debería ser "2", en lugar de 4 o 6.
function hexToR($h) {
return hexdec(substr(cutHex($h), 0, 2));
}
function hexToG($h) {
return hexdec(substr(cutHex($h), 2, 2));
}
function hexToB($h) {
return hexdec(substr(cutHex($h), 4, 2));
}
Además de las soluciones aritméticas, también es posible utilizar una red neuronal AI. La ventaja es que puede adaptarlo a su gusto y necesidades (es decir, el texto blanco apagado en rojos satinados brillantes se ve bien y es tan legible como negro).
Aquí hay una demo de JavaScript ordenada que ilustra el concepto. También puede generar su propia fórmula JS directamente en la demostración.
https://harthur.github.io/brain/
A continuación se encuentran algunos cuadros que me ayudaron a resolver el problema . En el primer gráfico, la luminosidad es una constante de 128, mientras que el tono y la saturación varían. En el segundo gráfico, la saturación es una constante de 255, mientras que el tono y la luminosidad varían.
Aquí está mi solución en Java para Android:
// Put this method in whichever class you deem appropriate
// static or non-static, up to you.
public static int getContrastColor(int colorIntValue) {
int red = Color.red(colorIntValue);
int green = Color.green(colorIntValue);
int blue = Color.blue(colorIntValue);
double lum = (((0.299 * red) + ((0.587 * green) + (0.114 * blue))));
return lum > 186 ? 0xFF000000 : 0xFFFFFFFF;
}
// Usage
// If Color is represented as HEX code:
String colorHex = "#484588";
int color = Color.parseColor(colorHex);
// Or if color is Integer:
int color = 0xFF484588;
// Get White (0xFFFFFFFF) or Black (0xFF000000)
int contrastColor = WhateverClass.getContrastColor(color);
Basándome en mi respuesta a una pregunta similar .
Debes dividir el código hexadecimal en 3 partes para obtener las intensidades individuales de rojo, verde y azul. Cada 2 dígitos del código representan un valor en notación hexadecimal (base-16). No entraré en los detalles de la conversión aquí, son fáciles de buscar.
Una vez que tenga las intensidades para los colores individuales, puede determinar la intensidad general del color y elegir el texto correspondiente.
if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff
Editar: Lo anterior es simple y funciona razonablemente bien, y parece tener una buena aceptación aquí en . Sin embargo, uno de los comentarios a continuación muestra que puede conducir al incumplimiento de las pautas W3C en algunas circunstancias. Con esto derivo una forma modificada que siempre elige el contraste más alto basado en las pautas.
La fórmula dada para el contraste en las Recomendaciones W3C es (L1 + 0.05) / (L2 + 0.05)
, donde L1
es la luminancia del color más claro y L2
es la luminancia más oscura en una escala de 0.0-1.0. La luminancia del negro es 0.0 y el blanco es 1.0, por lo que sustituir esos valores le permite determinar el que tiene el mayor contraste. Si el contraste para negro es mayor que el contraste para blanco, use negro, de lo contrario use blanco. Dada la luminancia del color que está probando como L
la prueba se convierte en:
if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff
Esto simplifica algebraicamente a:
if L > sqrt(1.05 * 0.05) - 0.05
O aproximadamente:
if L > 0.179 use #000000 else use #ffffff
Lo único que queda es calcular L
Esa fórmula también se da en las directrices y parece la conversión de sRGB a RGB lineal seguido de la recomendación ITU-R BT.709 para luminancia.
for each c in r,g,b:
c = c / 255.0
if c <= 0.03928 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4
L = 0.2126 * r + 0.7152 * g + 0.0722 * b
Basado en la respuesta de @MarkRansom, creé un script PHP que puedes encontrar aquí:
function calcC($c) {
if ($c <= 0.03928) {
return $c / 12.92;
}
else {
return pow(($c + 0.055) / 1.055, 2.4);
}
}
function cutHex($h) {
return ($h[0] == "#") ? substr($h, 1, 7) : $h;
}
function hexToR($h) {
return hexdec(substr(cutHex($h), 0, 2));
}
function hexToG($h) {
return hexdec(substr(cutHex($h), 2, 2)); // Edited
}
function hexToB($h) {
return hexdec(substr(cutHex($h), 4, 2)); // Edited
}
function computeTextColor($color) {
$r = hexToR($color);
$g = hexToG($color);
$b = hexToB($color);
$uicolors = [$r / 255, $g / 255, $b / 255];
$c = array_map("calcC", $uicolors);
$l = 0.2126 * $c[0] + 0.7152 * $c[1] + 0.0722 * $c[2];
return ($l > 0.179) ? ''#000000'' : ''#ffffff'';
}
Este es solo un ejemplo que cambiará el color de una marca de verificación SVG al hacer clic en un elemento. Establecerá el color de la marca de verificación en negro o blanco en función del color de fondo del elemento cliqueado.
checkmarkColor: function(el) {
var self = el;
var contrast = function checkContrast(rgb) {
// @TODO check for HEX value
// Get RGB value between parenthesis, and remove any whitespace
rgb = rgb.split(//(([^)]+)/)/)[1].replace(/ /g, '''');
// map RGB values to variables
var r = parseInt(rgb.split('','')[0], 10),
g = parseInt(rgb.split('','')[1], 10),
b = parseInt(rgb.split('','')[2], 10),
a;
// if RGBA, map alpha to variable (not currently in use)
if (rgb.split('','')[3] !== null) {
a = parseInt(rgb.split('','')[3], 10);
}
// calculate contrast of color (standard grayscale algorithmic formula)
var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000;
return (contrast >= 128) ? ''black'' : ''white'';
};
$(''#steps .step.color .color-item .icon-ui-checkmark-shadow svg'').css({
''fill'': contrast($(self).css(''background-color''))
});
}
onClickExtColor: function(evt) {
var self = this;
self.checkmarkColor(evt.currentTarget);
}
MENOS tiene una buena función de contrast()
que funcionó bien para mí, ver http://lesscss.org/functions/#color-operations-contrast
"Elija cuál de los dos colores proporciona el mayor contraste con otro. Esto es útil para garantizar que un color sea legible sobre un fondo, lo que también es útil para el cumplimiento de accesibilidad. Esta función funciona de la misma manera que la función de contraste en Compass for SASS. De acuerdo con WCAG 2.0, los colores se comparan utilizando su valor de luma corregido gamma, no su ligereza ".
Ejemplo:
p {
a: contrast(#bbbbbb);
b: contrast(#222222, #101010);
c: contrast(#222222, #101010, #dddddd);
d: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 30%);
e: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 80%);
}
Salida:
p {
a: #000000 // black
b: #ffffff // white
c: #dddddd
d: #000000 // black
e: #ffffff // white
}
No me atribuyo el mérito de este código ya que no es mío, pero lo dejo aquí para que otros puedan encontrarlo rápidamente en el futuro:
Según la respuesta de Mark Ransoms, aquí hay un fragmento de código para la versión simple:
function pickTextColorBasedOnBgColorSimple(bgColor, lightColor, darkColor) {
var color = (bgColor.charAt(0) === ''#'') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ?
darkColor : lightColor;
}
y aquí está el fragmento de código para la versión avanzada:
function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
var color = (bgColor.charAt(0) === ''#'') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
var uicolors = [r / 255, g / 255, b / 255];
var c = uicolors.map((col) => {
if (col <= 0.03928) {
return col / 12.92;
}
return Math.pow((col + 0.055) / 1.055, 2.4);
});
var L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
return (L > 0.179) ? darkColor : lightColor;
}
Para usarlos solo llame:
var color = ''#EEACAE'' // this can be any color
pickTextColorBasedOnBgColorSimple(color, ''#FFFFFF'', ''#000000'');
Además, gracias Alx
y chetstone
.
Nunca he hecho algo como esto, pero ¿qué hay de escribir una función para verificar los valores de cada uno de los colores contra el color mediano de Hex 7F (FF / 2). Si dos de los tres colores son mayores que 7F, entonces estás trabajando con un color más oscuro.
Uso esta función de JavaScript para convertir rgb
/ rgba
en ''white''
o ''black''
.
function getTextColor(rgba) {
rgba = rgba.match(//d+/g);
if ((rgba[0] * 0.299) + (rgba[1] * 0.587) + (rgba[2] * 0.114) > 186) {
return ''black'';
} else {
return ''white'';
}
}
Puede ingresar cualquiera de estos formatos y obtendrá ''black''
o ''white''
-
rgb(255,255,255)
-
rgba(255,255,255,0.1)
-
color:rgba(255,255,255,0.1)
-
255,255,255,0.1