2010-06-10 3 views
28

Je souhaite que les utilisateurs de mon site Web puissent sélectionner une couleur hexadécimale, et je souhaite simplement afficher un texte en blanc pour les couleurs sombres et un texte en noir pour les couleurs claires. Pouvez-vous calculer la luminosité à partir d'un code hexadécimal (de préférence PHP)?Hex Code Luminosité PHP?

Répondre

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

Fonctionne parfaitement, n'a même pas besoin d'aller dans la teinte et la saturation! :) – Juddling

+0

Dans mon cas, il est préférable d'utiliser 250 au lieu de 382. Je ne pense pas que la couleur verte complète (# 00ff00) devrait utiliser une police de couleur claire, et le rouge complet est bien avec une couleur sombre. Je dis juste. –

2

Vous devez convertir les valeurs RVB en HLS/HSL (Teinte Luminosité et Saturation), vous pouvez ensuite utiliser la Légèreté pour déterminer si vous avez besoin de texte clair ou de texte foncé.

This page a quelques détails sur la façon dont la conversion en PHP ainsi que la sélection de couleurs complémentaires à partir de cela.

Je viens seulement de remarquer que le site est un site d'astrologie - alors, excusez-moi si quelqu'un est offensé.

+1

sur le site de l'astrologie: oui, c'est ** horrible ** (Non, je plaisante, intéressante, ils ont une telle programmation sujet connexe sur leur site, je! ne m'y attendrais pas. –

+0

@Marcel - Je pense que c'est pour montrer le code derrière leurs cartes. – ChrisF

1

Si vous avez l'extension de ImageMagick est activée, vous pouvez simplement créer un objet ImagickPixel, appelez setColor avec votre valeur hexadécimale, puis appelez getHSL() (et obtenir le dernier élément du tableau obtenu, je suppose) ...

17

J'ai fait semblable - mais en fonction des pondérations de chaque couleur (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: optimisation Petit: Sqrt est connu comme une opération mathématique coûteuse, qui est probablement négligeable dans la plupart des scénarios, mais de toute façon, il pourrait être évité en faisant quelque chose comme ça.

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 

Il ne s'applique tout simplement pas le sqrt, au lieu il alimente le contraste coupé désiré par deux, ce qui est un calcul

+0

C'est génial! Merci! –

+0

pour obtenir les valeurs RVB en dec juste utiliser cette ligne: 'liste ($ r, $ g, $ b) = sscanf ($ couleur,"% 02x% 02x% 02x ");' ou si $ couleur commence par un # 'liste ($ r, $ g, $ b) = sscanf ($ couleur," #% 02x% 02x% 02x ");' – JoTaRo

1

Je sais que cela est beaucoup moins cher un sujet très ancien, mais pour les utilisateurs qui vient de "Google Search", ce lien peut être ce qu'ils recherchent. Je l'ai cherché quelque chose comme ça et je pense que c'est une bonne idée de poster ici:

https://github.com/mexitek/phpColors

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

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

Voilà.

0

J'ai essayé une approche différente, j'ai utilisé le pourcentage de clarté HSL (teinte, saturation &) pour vérifier si la couleur est sombre ou claire. (Comme @chrisf dit dans sa réponse)

fonction :

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); 
} 

Sur la ligne de retour, il vérifie si le pourcentage de légèreté est supérieure à 50% et renvoie true sinon false est retourné. Vous pouvez facilement le changer pour retourner vrai si la couleur a 30% de légèreté et ainsi de suite. La variable $lightness peut retourner de 0 à 100 0 étant le plus sombre et 100 étant le plus léger.

comment utiliser la fonction:

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