« »
1/25/2009

Choix automatique de la couleur d'un texte en fonction de sa couleur d'arrière plan

Ou en terme plus technique, comment créer un algorithme qui retourne un foregroundColor adéquate en fonction d'un backgroundColor variable.

Dans le cadre de mon stage @ Zlio Nantes, j'ai eu besoin de créer un algorithme qui, à partir de n'importe quelle couleur d'arrières plans, serait capable de définir si la couleur du texte (blanc ou noir) afin que ce dernier soit toujours visible.

Postulat : Pour la démonstration, nous prendrons un vert foncé comme couleur d'arrière plan

#155147 = rgb(21, 81, 71); //RGB (Red, Blue, Green) ou RVB (Rouge, Vert, Bleu)

 

Méthode rapide

La première idée qui pourrait vous venir à l'esprit serait d' additionner les composantes RVB :

21+81+71 = 173

Or, au maximum il est possible d'obtenir une somme de

255+255+255 = 765

Donc il suffirait donc de regarder si la somme des composantes et supérieur ou inférieur à 382,5 (765/2) pour savoir s'il faut mettre le texte en blanc (donc plus clair) ou en noir (plus foncé). Ce qui pourrait donner cet algorithme :

var couleurRGB = [21,81,71];

Si couleurRGB[0]+couleurRGB[1]+couleurRGB[2] > 382 Alors
     //#FFFFFF
Sinon
     //#000000
FinSi

En réalité cet approche est fausse. D'ailleurs en utilisant la couleur de l'exemple, l'algorithme nous propose d'utiliser du noir. Voici le résultat :

En testant on constate que le texte n'est clairement pas visible et que le blanc aurait été un meilleur choix.

 

En baissant la valeur seuil à 170 notre algorithme retourne une couleur correcte (blanc) pour notre exemple, mais qu'en est-il pour ces autres couleurs ? rgb(4, 1, 31), rgb(9, 23, 9), rgb(29, 50, 3), rgb(27, 15, 27). La somme de leurs composantes ne dépasse pas 170 et pourtant la proposition est fausse, notre algorithme propose du noir.

Pour corriger cela nous pourrions baisser la valeur seuil. Lors de mes tests j'ai réussi à obtenir de très bon résultat avec une valeur seuil à 86 mais il reste encore une infinité de cas où notre algorithme propose une couleur erronée.

A ce stade, 2 possibilités. Soit nous complexifions notre algorithme en étudiant chacune des composants les une après les autres et en réalisant un savant mélange de test,... Soit nous passons à la méthode fiable.

 

Méthode fiable

La méthode fiable consiste à convertir le format de gestion de couleur de RGB vers HSL (Hue, Saturation, Lightness) soit TSL (Teinte, Saturation, Lumière) en français. C'est la composante lumière qui nous intéresse :

La lumière est la luminosité (depuis 0 % qui correspond au noir jusqu'à 100 %, luminosité maximale permise par le support, le blanc dans le cas des écrans).

Une fois la conversion effectuée ils nous suffira de définir si la composante "L" est supérieur ou inférieur à 50% et d'en déduire la couleur à appliquer en premier plan. Notre algorithme devient donc :

var couleurRGB = [21,81,71];
var couleurHSL = RGBtoHSL(couleurRGB);

Si couleurHSL[2] > 0.5 Alors //0.5 = 50% 
     //#000000
Sinon
     //#FFFFFF
FinSi 

Et voila ! Cette méthode est légèrement plus lente en calcul processeur car elle nécessite une conversion supplémentaire mais elle est 100% fiable.

[MAJ] La démo est disponible en ligne ici, elle intègre le code javascript fonctionnel des deux algorithmes ainsi qu'un script de test pour comparer automatiquement leurs valeurs de retour.

« »
 
 
Made with on a hot august night.
http://bit.ly/1II1u5L