ACCUEIL > TUTORIAUX SPIP

UNE PALETTE DE COULEURS AUTOMATIQUE

   

[SPIP 1.9 et GD2] Une habitude très utile lorsqu’on construit l’interface graphique d’un site Web consiste à choisir un nombre restreint de couleurs (par exemple, 3 couleurs), ce qui revient à définir une palette de couleurs, et à réaliser le site en n’utilisant que ces couleurs. Cela garantit au site un grande cohérence graphique, même lorsque les contenus et les maquettes sont différentes d’une page à l’autre [1].

Pour créer et manipuler les couleurs, SPIP 1.9 fournit un ensemble de filtres destinés à exploiter une couleur tirée d’une image. Je vous conseille vivement de vous pencher sur cet aspect de SPIP, il permet, subtilement, de modifier sa palette graphique en fonction d’images (logos par exemple) associées à la page affichée.

Si la maquette du site est suffisamment forte (i.e. la structure graphique est reconnaissable immédiatement d’une page à l’autre), on peut ainsi introduire des éléments dont la couleur change, ce qui à la fois donne de la diversité aux pages, mais aussi permet d’utiliser des couleurs cohérentes avec les images. Par exemple, on peut afficher la description d’une image dans un pavé de texte dont le fond est une couleur tirée de cette image.

Voici par exemple une image avec, en dessous, un pavé d’une couleur tirée de cette image :

L’article qui suit va tenter de dépasser l’utilisation d’une unique couleur extraite pour créer une palette complète. À partir de la couleur extraite (ici un orange foncé), nous allons fabriquer automatiquement d’autres couleurs. Les filtres de SPIP permettent de créer des variantes foncées et éclaircies d’une couleur, ici nous allons trouver d’autres teintes.

Une méthode fréquente consiste à utiliser une roue chromatique. Il s’agit d’un cercle dans lequel on place notre couleur de référence ; en « tournant » régulièrement autour de cette roue, on obtiendra d’autres couleurs, de teinte nettement différente de notre couleur d’origine, mais dont la saturation et la luminosité seront identiques.

Dans l’image ci-dessus, nous avons indiqué notre orange foncé.

Parcourons notre roue selon six « angles » également espacés (nous prenons le chiffre 6 pour les besoins de l’explication, absolument n’importe quelle autre subdivision est possible) :

Si nous récupérons les six couleurs ainsi obtenues, nous avons une palette de six couleurs, dont les teintes sont espacées régulièrement sur la roue. Nous pouvons tout aussi bien décider de n’utiliser que trois couleurs, chiffre assez habituel pour une palette utilisable sur un site Web ; nous pouvons utiliser des couleurs espacées régulièrement (1, 3, 5), ou décider de rester « près » de notre couleur d’origine (1, 2, 6)...

Pour jouer en direct avec une roue chromatique, n’hésitez pas à visiter le site WellStyled, il fournit en ligne un outil très pratique.

Visuellement, la logique est très simple. Il faut maintenant la transformer en logique informatique. Le codage RVB, que nous utilisons habituellement sur le Web pour décrire les couleurs, ne donne pas accès directement à la « teinte » d’une couleur. Cependant, nous avons déjà évoqué cette limitation, et nous l’avons déjà contournée. Dans notre article sur un filtre de saturation/désaturation, nous avons présenté le codage HSV (hue, saturation, value), qui donne directement accès à l’information de teinte (hue) [2]

Dans le codage HSV, la valeur hue est, très exactement, la position de la couleur sur la roue chromatique : 0 est le rouge, puis en augmentant cette valeur (jusqu’à 100% dans notre cas, jusqu’à 360° dans une logique Photoshop), on parcourt la roue ci-dessus dans le sens des aiguilles d’une montre.

Commençons par reprendre les deux fonctions PHP qui convertissent du RVB en HSV (et inversement), que nous avions développées pour le filtre de désaturation :

  1. function image_rgb2hsv ($R,$G,$B) {
  2.         $var_R = ( $R / 255 ) ;                    //Where RGB values = 0 ÷ 255
  3.         $var_G = ( $G / 255 );
  4.         $var_B = ( $B / 255 );
  5.         $var_Min = min( $var_R, $var_G, $var_B ) ;   //Min. value of RGB
  6.         $var_Max = max( $var_R, $var_G, $var_B ) ;   //Max. value of RGB
  7.         $del_Max = $var_Max - $var_Min  ;           //Delta RGB value
  8.         $V = $var_Max;
  9.         $L = ( $var_Max + $var_Min ) / 2;
  10.        
  11.         if ( $del_Max == 0 )                     //This is a gray, no chroma...
  12.         {
  13.            $H = 0 ;                            //HSL results = 0 ÷ 1
  14.            $S = 0 ;
  15.         }
  16.         else                                    //Chromatic data...
  17.         {
  18.            $S = $del_Max / $var_Max;
  19.        
  20.            $del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
  21.            $del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
  22.            $del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
  23.        
  24.            if      ( $var_R == $var_Max ) $H = $del_B - $del_G;
  25.            else if ( $var_G == $var_Max ) $H = ( 1 / 3 ) + $del_R - $del_B;
  26.            else if ( $var_B == $var_Max ) $H = ( 2 / 3 ) + $del_G - $del_R;
  27.        
  28.            if ( $H < 0 )  $H =  $H + 1;
  29.            if ( $H > 1 )  $H = $H - 1;
  30.         }
  31.                                
  32.         $ret["h"] = $H;
  33.         $ret["s"] = $S;
  34.         $ret["v"] = $V;
  35.        
  36.         return $ret;
  37. }
  38. function image_hsv2rgb ($H,$S,$V) {
  39.         if ( $S == 0 )                       //HSV values = 0 ÷ 1
  40.         {
  41.            $R = $V * 255;
  42.            $G = $V * 255;
  43.            $B = $V * 255;
  44.         }
  45.         else
  46.         {
  47.            $var_h = $H * 6;
  48.            if ( $var_h == 6 ) $var_h = 0 ;     //H must be < 1
  49.            $var_i = floor( $var_h )  ;           //Or ... var_i = floor( var_h )
  50.            $var_1 = $V * ( 1 - $S );
  51.            $var_2 = $V * ( 1 - $S * ( $var_h - $var_i ) );
  52.            $var_3 = $V * ( 1 - $S * ( 1 - ( $var_h - $var_i ) ) );
  53.        
  54.            if      ( $var_i == 0 ) { $var_r = $V     ; $var_g = $var_3 ; $var_b = $var_1 ; }
  55.            else if ( $var_i == 1 ) { $var_r = $var_2 ; $var_g = $V     ; $var_b = $var_1 ; }
  56.            else if ( $var_i == 2 ) { $var_r = $var_1 ; $var_g = $V     ; $var_b = $var_3 ; }
  57.            else if ( $var_i == 3 ) { $var_r = $var_1 ; $var_g = $var_2 ; $var_b = $V ;     }
  58.            else if ( $var_i == 4 ) { $var_r = $var_3 ; $var_g = $var_1 ; $var_b = $V ; }
  59.            else                   { $var_r = $V     ; $var_g = $var_1 ; $var_b = $var_2; }
  60.        
  61.            $R = $var_r * 255;                  //RGB results = 0 ÷ 255
  62.            $G = $var_g * 255;
  63.            $B = $var_b * 255;
  64.         }
  65.         $ret["r"] = floor($R);
  66.         $ret["g"] = floor($G);
  67.         $ret["b"] = floor($B);
  68.        
  69.         return $ret;
  70. }

Voici maintenant notre filtre de roue chromatique :

  1. function couleur_chroma ($coul, $num) {
  2.         $pos = substr($num, 0, strpos($num, "/")) -  1;
  3.         $tot = substr($num, strpos($num, "/")+1, strlen($num));
  4.        
  5.         include_ecrire("filtres");
  6.         $couleurs = couleur_hex_to_dec($coul);
  7.         $r= $couleurs["red"];
  8.         $g= $couleurs["green"];
  9.         $b= $couleurs["blue"];
  10.         $hsv = image_rgb2hsv($r,$g,$b);
  11.         $h = $hsv["h"];
  12.         $s = $hsv["s"];
  13.         $v = $hsv["v"];
  14.        
  15.         $h = $h + (1/$tot)*$pos;
  16.         if ($h > 1) $h = $h - 1;
  17.                                        
  18.         $rgb = image_hsv2rgb($h,$s,$v);
  19.         $r = $rgb["r"];
  20.         $g = $rgb["g"];
  21.         $b = $rgb["b"];
  22.        
  23.         $couleurs = couleur_dec_to_hex($r, $g, $b);
  24.        
  25.         return $couleurs;
  26. }

On lui passe la valeur de la couleur codée en RVB hexadécimale (de la forme FFFFFF), et la « position » de la couleur désirée sur la roue chromatique (de la forme 3/6, signifiant la troisième couleur en découpant la roue en six portions).

On commence par extraire les valeurs de position et le nombre de tranches de la roue (3 et 6) :

  1.         $pos = substr($num, 0, strpos($num, "/")) -  1;
  2.         $tot = substr($num, strpos($num, "/")+1, strlen($num));

On transforme la couleur RVB hexadécimale en ses trois composantes R, V et B décimales (de 0 à 255) :

  1.         include_ecrire("filtres");
  2.         $couleurs = couleur_hex_to_dec($coul);
  3.         $r= $couleurs["red"];
  4.         $g= $couleurs["green"];
  5.         $b= $couleurs["blue"];

On convertit en HSV :

  1.         $hsv = image_rgb2hsv($r,$g,$b);
  2.         $h = $hsv["h"];
  3.         $s = $hsv["s"];
  4.         $v = $hsv["v"];

Voici le code de transformation proprement dit :

  1.         $h = $h + (1/$tot)*$pos;
  2.         if ($h > 1) $h = $h - 1;

On « décale » maintenant notre teinte dans la roue chromatique. La valeur « 1 » qui apparaît plusieurs fois est égale aux « 100% » que l’on utilise dans notre codage HSV (dans Photoshop, on travaillerait avec une logique basée sur 360°).

Enfin on passe cette nouvelle valeur (on n’a changé que la teinte ; la saturation et la luminosité sont inchangées) en trois composantes R, V et B décimales, que l’on convertit ensuite en RVB hexadécimal ; c’est cette valeur que l’on retourne :

  1.         $rgb = image_hsv2rgb($h,$s,$v);
  2.         $r = $rgb["r"];
  3.         $g = $rgb["g"];
  4.         $b = $rgb["b"];
  5.        
  6.         $couleurs = couleur_dec_to_hex($r, $g, $b);
  7.        
  8.         return $couleurs;

L’utilisation du filtre se fait ainsi :

  1. background-color: #[(#FICHIER|couleur_extraire|couleur_chroma{3/6})]

On extrait une couleur de l’image, puis on demande la troisième couleur sur la roue chromatique divisée en six portions.

Si l’on affiche les six couleurs extraites (la couleur 1 est toujours la couleur d’origine), on obtient la palette suivante :

Appliquée à une autre image, la couleur extraite est plus « pastel » ; on constate que la palette graphique présente bien six teintes différentes, mais qui sont toutes bien des pastels :

[1] J’en profite pour signaler l’existence d’un widget très sympathique, ColorBurn, qui fournit chaque jour une palette de quatre couleurs toujours bien choisie. Ce widget est disponible pour Dashboard (MacOS X Tiger) et Yahoo Widgets (MacOS et Win XP).

[2] Lisez ou relisez cet article pour comprendre le codage HSV.


modération à priori

Ce forum est modéré à priori : votre contribution n'apparaîtra qu'après avoir été validée par un administrateur du site.

Un message, un commentaire ?
  • (Pour créer des paragraphes, laissez simplement des lignes vides.)

Qui êtes-vous ? (optionnel)