2010-06-10 15 views
28

Quiero que los usuarios de mi sitio web puedan elegir un color hexadecimal, y solo quiero mostrar texto blanco para colores oscuros y texto negro para colores claros. ¿Puedes calcular el brillo de un código hexadecimal (preferiblemente PHP)?Brillo de código hexadecimal PHP?

Respuesta

40
$hex = "78ff2f"; //Bg color in hex, without any prefixing #! 

//break up the color in its RGB components 
$r = hexdec(substr($hex,0,2)); 
$g = hexdec(substr($hex,2,2)); 
$b = hexdec(substr($hex,4,2)); 

//do simple weighted avarage 
// 
//(This might be overly simplistic as different colors are perceived 
// differently. That is a green of 128 might be brighter than a red of 128. 
// But as long as it's just about picking a white or black text color...) 
if($r + $g + $b > 382){ 
    //bright color, use dark font 
}else{ 
    //dark color, use bright font 
} 
+0

¡Funciona perfecto, ni siquiera necesita entrar en Hue y Saturation! :) – Juddling

+0

En mi caso, funcionó mejor usar 250 en lugar de 382. No creo que el color verde completo (# 00ff00) use una fuente de color claro, y el rojo completo esté bien con un color oscuro. Solo digo. –

2

Necesita convertir los valores RGB a HLS/HSL (Matiz de luminosidad y saturación) puede utilizar la luminosidad para determinar si necesita texto claro o oscuro.

This page tiene algunos detalles sobre cómo la conversión en PHP, así como la selección de colores complementarios a partir de esto.

Acabo de descubrir que el sitio es un sitio de astrología, así que me disculpo si alguien se ofendió.

+1

Sobre sitio de la astrología: sí, eso es horrible ** ** (No, es broma, interesante que tienen un tema relacionado con este tipo de programación en su sitio, yo! no esperaría eso.) –

+0

@Marcel - Creo que es para mostrar el código detrás de sus gráficos. – ChrisF

1

Si ha activado la extensión ImageMagick, sólo tiene que crear un objeto ImagickPixel, llame setColor con su valor hexadecimal, y luego llamar a getHSL() (y obtener el último elemento de la matriz obtenida supongo) ...

17

me hizo una similar - pero en base a las ponderaciones de cada color (based on the C# version of this thread)

function readableColour($bg){ 
    $r = hexdec(substr($bg,0,2)); 
    $g = hexdec(substr($bg,2,2)); 
    $b = hexdec(substr($bg,4,2)); 

    $contrast = sqrt(
     $r * $r * .241 + 
     $g * $g * .691 + 
     $b * $b * .068 
    ); 

    if($contrast > 130){ 
     return '000000'; 
    }else{ 
     return 'FFFFFF'; 
    } 
} 

echo readableColour('000000'); // Output - FFFFFF 

EDIT: Pequeño optimización: Sqrt se conoce como una costosa operación matemática, que probablemente es poco útil en la mayoría de los escenarios, pero de todos modos, se podría evitar haciendo algo como esto.

function readableColour($bg){ 
    $r = hexdec(substr($bg,0,2)); 
    $g = hexdec(substr($bg,2,2)); 
    $b = hexdec(substr($bg,4,2)); 

    $squared_contrast = (
     $r * $r * .299 + 
     $g * $g * .587 + 
     $b * $b * .114 
    ); 

    if($squared_contrast > pow(130, 2)){ 
     return '000000'; 
    }else{ 
     return 'FFFFFF'; 
    } 
} 

echo readableColour('000000'); // Output - FFFFFF 

Simplemente no se aplica la raíz cuadrada, en vez que se enciende el punto de corte de contraste deseado por dos, que es un cálculo mucho más barato

+0

¡Esto es simplemente genial! ¡Gracias! –

+0

para obtener valores RGB en dec solo use esta línea: 'list ($ r, $ g, $ b) = sscanf ($ color,"% 02x% 02x% 02x ");' o si $ color comienza con # 'list ($ r, $ g, $ b) = sscanf ($ color," #% 02x% 02x% 02x ");' – JoTaRo

1

Sé que esto es un tema muy antiguo, pero para los usuarios que vino de "Búsqueda de Google", este enlace puede ser lo que están buscando. He buscado para algo como esto y yo creo que es una buena idea para publicar aquí:

https://github.com/mexitek/phpColors

use Mexitek\PHPColors\Color; 
// Initialize my color 
$myBlue = new Color("#336699"); 

echo $myBlue->isLight(); // false 
echo $myBlue->isDark(); // true 

Eso es todo.

0

Probé un enfoque diferente para esto, utilicé HSL (tono, saturación & luminosidad) porcentaje de luminosidad para comprobar si el color es oscuro o claro. (Como @chrisf dicho en su respuesta)

función:

function colorislight($hex) { 
    $hex  = str_replace('#', '', $hex); 
    $r   = (hexdec(substr($hex, 0, 2))/255); 
    $g   = (hexdec(substr($hex, 2, 2))/255); 
    $b   = (hexdec(substr($hex, 4, 2))/255); 
    $lightness = round((((max($r, $g, $b) + min($r, $g, $b))/2) * 100)); 
    return ($lightness >= 50 ? true : false); 
} 

En la línea de retorno se comprueba si el porcentaje ligereza es mayor que 50% y devuelve verdadero lo contrario se devuelve false. Puede cambiarlo fácilmente para que sea verdadero si el color tiene un 30% de luminosidad y así sucesivamente. La variable $lightness puede regresar de 0 a 100 0 siendo la más oscura y 100 la más clara.

cómo utilizar la función:

$color = '#111111'; 
if (colorislight($color)) { 
    echo 'this color is light'; 
} 
else { 
    echo 'this color is dark'; 
} 
Cuestiones relacionadas