| 
       Génération d'images avec PHP  | 
  
    | 
      
          | 
  
    La librairie 
      graphique  | 
  
    | 
        Sous Windows, la librairie graphique 
      se nomme "php_gd.dll". Elle permet de 
      manipuler des images au format PNG, JPEG, WBMP et SWF.  
      
        - Le format Gif a été abandonné pour des 
        raisons de copyright. Par contre, le PNG le 
        remplace avantageusement, prenant en charge les couleurs 8 bits et, ce qui est plus important, 24 bits. Une image PNG 24 
        bits préservera la netteté du 
        dessin et la transparence du fond 
        (Gif), ainsi que la subtilité des couleurs 
        (Jpeg), sans perte de données. 
        
 - Le format JPEG est le plus utilisé sur 
        le Web, pour son taux de compression élévé (avec 
        perte de données). 
        
 - Le format WBMP est particulier au 
        WAP. 
        
 - Le format SWF nécessite le plug-in Flash. 
  
         | 
  
    | Installation et 
      configuration | 
  
    | 
        La librairie php_gd.dll se trouve 
      dans le package complet de PHP 4. Vous 
      pouvez télécharger la dernière version de GD ici. Pour charger automatiquement la dll, enlevez simplement le ";" en début de ligne dans le fichier php.ini (le fichier de configuration de PHP, situé 
      dans WINNT ou Windows), section "Dynamic 
      Extensions". Assurez-vous également que le chemin du répertoire 
      contenant la dll est correct, dans la section "Paths and Directories", ex : "extension_dir = 
      C:\php\extensions" 
         | 
  
    | Rééchantillonnage d'une image | 
  
    | 
        Une des utilisations les plus interessantes de GD est le rééchantillonnage d'images. Dans cet exemple, nous 
      allons retailler une image JPEG à 50% de sa taille 
      originale.  Le principe est le suivant :  
      
        - créer une image noire en vraies couleurs de la taille de l'image de 
        destination 
        
 - copier et rééchantillonner les pixels de l'image originale 
        
 - générer l'image dans le flux de sortie standard (navigateur) 
  
      
        <?
Header("Content-type: image/jpeg");
$src_im = ImageCreateFromJpeg("palmier.jpg");
$src_w = imageSX($src_im);
$src_h = imageSY($src_im);
$dst_w = floor($src_w * 0.5);
$dst_h = floor($src_h * 0.5);
/* ImageCreateTrueColor crée  une image noire en vraie couleurs */
$dst_im = ImageCreateTrueColor($dst_w,$dst_h);
/* ImageCopyResampled copie et rééchantillonne l'image originale*/
ImageCopyResampled($dst_im,$src_im,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
/* ImageJpeg génère l'image dans la sortie standard (c.à.d le navigateur).
Le second paramètre est optionnel ; dans ce cas, l'image est générée dans un fichier*/
ImageJpeg($dst_im);
ImageDestroy($dst_im);
imageDestroy($src_im);
?> 
               
      Si vous souhaitez contraindre le rééchantillonnage à une valeur fixe en 
      hauteur ou en largeur, vous pouvez procéder ainsi :  
      <?
$size = GetImageSize("palmier.jpg"); $src_w = $size[0]; $src_h = $size[1]; $dst_w = 150; // Contraint le rééchantillonage à une largeur fixe $dst_h = round(($dst_w / $src_w) * $src_h); // Maintient le ratio de l'image
?> 
         | 
  
    | Mode Batch | 
  
    | 
        Pour utiliser cet exemple en mode 
      batch (traitement par lots), il 
      suffit de modifier le script pour en faire une fonction. On parcourt 
      ensuite le répertoire contenant les images originales, et, à chaque image 
      Jpeg rencontrée, on appelle la fonction redim() en lui passant en second argument le 
      répertoire de destination. 
      <?
function redim($im_src,$im_dest) {
           $size = GetImageSize($im_src);
           $src_w = $size[0];
           $src_h = $size[1];
           $dst_w = floor($src_w * 0.5);
           $dst_h = floor($src_h * 0.5);
           $dst_im = ImageCreateTrueColor($dst_w,$dst_h);
           $src_im = ImageCreateFromJpeg($im_src);
           ImageCopyResampled($dst_im,$src_im,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
           ImageJpeg($dst_im,$im_dest);
           ImageDestroy($dst_im);
           imageDestroy($src_im);
 }
$dst_dir = "thumbnails"; // le répertoire qui stockera les images redimensionnées
if(!file_exists($dst_dir)) 
           mkdir($dst_dir,0700); // crée le répertoire s'il n'existe pas
$src_dir = ".";
$dir = opendir($src_dir);
while($im = readdir($dir))
{
// ne prend que les images Jpeg
           if(strtolower(substr($im)),-3) == "jpg" || strtolower(substr($im,-4)) == "jpeg") { 
                      redim($im,$dst_dir."/50_".$im); // préfixe le nom des images avec "50_"
                      $i++;
           } 
}
closedir($dir);
?>
 
         | 
  
    | Dessin d'une 
      chaîne de caractères | 
  
    | 
        GD ne sert pas seulement à redimensionner des images, mais permet 
      de manipuler du texte. GD écrit le texte soit avec une police par défaut 
      (bitmap), soit une police TrueType ou PostScript. La fonction ImageString est utilisée pour écrire du texte 
      bitmap sur une image. L'exemple suivant crée 
      une image qui s'adapte en fonction de la dimension du texte.
  
      
      <?
$texte = "Ecriture de texte bitmap avec GD...";
$font_size = 3;
/* Calcule la longueur du texte en pixels */
$font_width = strlen($texte) * ImageFontWidth($font_size);
/* Calcule la hauteur du texte en pixels */
$font_height = ImageFontHeight($font_size);
/* Crée une image de la dimension du texte */
$image = ImageCreate($font_width,$font_height);
/* ImageColorAllocate alloue un fond blanc à l'image */
$white = ImageColorAllocate($image,255,255,255);
/* Définit la couleur du texte */
$black = ImageColorAllocate($image,0,0,0);
/* ImageString écrit le texte dans l'image */
ImageString($image,$font_size,0,0,$texte,$black);
Imagepng($image,"texte_bmp.png");
ImageDestroy($image);
?>  
        
      Comme vous pouvez le constater, le texte n'est pas anti-aliasé (lissé) ; de plus, vous n'avez pas 
      vraiment le choix de la police. Le second exemple vous montre comment 
      utiliser une police TrueType de votre choix, 
      ici arial bold italique (que vous pouvez télécharger 
      pour tester l'exemple). La fonction ImageTtfBBox retourne un tableau de 8 éléments 
      contenant les coordonnées du rectangle qui entoure le texte, ce qui permet 
      d'en calculer les dimensions en pixels. Le texte est tracé avec la 
      fonction ImageTtfText, qui, contrairement à 
      ImageString vue plus haut, prend pour 
      origine le coin inférieur gauche du premier caractère (la ligne de 
      base).
  Note 
      : pour cette raison, certaines polices de 
      caractère possédant un jambage 
      important peuvent être coupées à l'affichage. Si 
      le cas se produit, vous devrez faire des essais en augmentant la hauteur 
      de l'image. GD ne possède malheureusement pas de méthode permettant de 
      calculer les valeurs entre la ligne de base et les parties supérieures ou 
      inférieures de lettres comme "p" ou "b", comme en Java par 
      exemple. 
      
         
      
      <?
$corps = 30;
/* Le chemin du fichier de police True Type */
$font = "/WINNT/fonts/arialbi.ttf";
$texte = "Texte TrueType";
/* ImageTtfBBox retourne les dimensions du texte */
$size =ImageTtfBBox($corps,0,$font,$texte);
$dx = abs($size[2]-$size[0]);
$dy = abs($size[5]-$size[3]);
$xpad=10; $ypad=10;
$im = ImageCreate($dx+$xpad,$dy+$ypad);
$fond = ImageColorAllocate($im,255,255,255);
$couleur = ImageColorAllocate($im,255,210,100);
/* ImageTtfText dessine le texte en partant de la ligne de base du premier caractère */
ImageTtfText($im,$corps,0,(int)($xpad/2),$dy-(int)($ypad/2),$couleur,$font,$texte);
ImagePng($im,"texte_truetype.png");
ImageDestroy($im);
?>  
        
         | 
  
    | Tracés | 
  
    | 
        Avec GD, vous pouvez également tracer des lignes et tout type de 
      figure géométrique. Ces fonctions sont très utiles pour la génération 
      dynamique de graphiques. Voici un exemple simple d'utilisation de la 
      fonction ImageArc, qui sert habituellement à 
      dessiner des graphiques de type camembert. Le code suivant crée un 
      masque circulaire dans une image Jpeg. La fonction ImageArc trace des arcs d'ellipse. Puisque nous 
      souhaitons dessiner un cercle, la hauteur et la largeur de l'ellipse 
      devront être identiques, tandis que les valeurs de début et de fin de 
      l'arc seront respectivement 0° et 360 °. Nous utilisons ensuite la 
      fonction ImageFillToBorder pour remplir la 
      région de l'image limitée par la couleur de contour du cercle (noir). 
      <?
$image = imagecreatefromjpeg("palmier.jpg");
$largeur = imageSX($image); $hauteur = imageSY($image);
$centre_w = $largeur / 2; $centre_h = $hauteur / 2;
$diametre = round(min($largeur,$hauteur) / 2);
$noir = imagecolorallocate($image, 0, 0, 0);
imagearc($image, $centre_w, $centre_h, $diametre, $diametre, 0, 360, $noir);
imagefilltoborder($image, 0, 0, $noir, $noir);
$dst_im = imagecreatetruecolor($diametre,$diametre);
imagecopy($dst_im,$image,0,0,$centre_w - (int)($diametre / 2),
           $centre_h - (int)($diametre / 2),$diametre,$diametre);
imagejpeg($dst_im,"masque.jpg");
ImageDestroy($image);
ImageDestroy($dst_im);
?>
 
        
         | 
  
    | Transparence  | 
  
    | 
        Comme le format GIF, le PNG prend en charge la transparence. Dans cette section, nous ne 
      traiterons de la transparence que pour les images en mode couleurs indexées (8 bits). Dans ce mode, 
      chaque pixel peut contenir jusqu'à 256 
      couleurs (les 2 couleurs, noir et blanc, du mode bitmap élevées à 
      la puissance 8). Une table des couleurs, 
      située dans l'en-tête du fichier, comprend les références RVB des 256 couleurs qui composent 
      l'image. A chaque pixel de l'image est attribué un de ces 
      numéros.
  Reprenons la chaine de texte que nous avons dessinée plus 
      haut (avec une police true type). Nous allons changer la couleur de fond 
      de l'image sans toucher au texte. Ensuite, nous rendrons la couleur du 
      texte transparente afin de créer un masque avec la photo du palmier. En 
      mode couleurs indexées, il faut procéder en 2 étapes : 
      
        - retrouver la référence de la couleur 
        que nous souhaitons modifier ou rendre transparente 
        
 - attribuer de nouvelles valeurs RVB à 
        cette couleur 
  
      La fonction ImageColorAt permet de retrouver 
      l'index de la couleur d'un pixel. ImageColorSet attribue une couleur à l'index 
      identifié par ImageColorAt, tandis qu'ImageColorTransparent rend transparente la couleur 
      indexée. 
      Note : le texte a été 
      dessiné sans anti-aliasing pour permettre un détourage plus net. Pour 
      désactiver l'anti-aliasing, donnez un identifiant de couleur négatif à la 
      fonction ImageTtfText. 
      
      <?
$image = ImageCreateFromPng("texte_truetype.png");
/* ImageColorAt retourne l'index de la couleur du pixel situé aux coordonnées (x, y) 0, 0 */
$color = ImageColorAt($image,0,0);
/* ImageColorSet fixe une couleur à l'index identifié par ImageColorAt */
ImageColorSet ($image, $color, 0, 130, 255);
Imagepng($image,"fond_couleur.png");
ImageDestroy($image);
?>
 
        
      
      <?
$texte = ImageCreateFromPng("texte_truetype.png");
$image = ImageCreateFromPng("palmier.png");
$largeur_texte = imageSX($texte);
$hauteur_texte = imageSY($texte);
$largeur_image = imageSX($image);
$hauteur_image = imageSY($image);
$coord_x = floor(($largeur_image - $largeur_texte) / 2);
$coord_y = floor(($hauteur_image - $hauteur_texte) / 2);
$index = imagecolorexact($texte,255,210,100);
ImageColorTransparent($texte,$index);
imagecopy($image, $texte, $coord_x, $coord_y, 0, 0, $largeur_image, $hauteur_image);
imagecopy($texte, $image, 0, 0,$coord_x,$coord_y,$largeur_image, $hauteur_image);
imagepng($texte,"texte_transparent.png");
ImageDestroy($texte);
ImageDestroy($image);
?> 
        
         | 
  
    Effets  | 
  
     En allant plus loin avec les fonctions 
      d'images à palette, vous pouvez créer des effets intéressants.  La 
      fonction ImageCopyMerge fusionne deux 
      images, ce qui donne un effet de transparence au fond blanc : 
      <?
...
/* ImageCopyMerge fonctionne exactement comme ImageCopy, mais ajoute un paramètre*/
imagecopymerge($image, $texte, $coord_x, $coord_y, 0, 0, $largeur_image, $hauteur_image, 60);
...
?>
  
        
      L'exemple suivant simule une image en niveaux de gris en modifiant les valeurs RVB des index de la table des couleurs : 
      <?
$im = imageCreateFromPNG("palmier.png");
for($i=0;$i<imagecolorstotal ($im);$i++) 
{ 
           $color = ImageColorsForIndex($im,$i); 
           $rvb=.299 * ($color['red'])+ .587 * ($color['green'])+ .114 * ($color['blue']); 
           ImageColorSet($im, $i, $rvb, $rvb, $rvb);
} imagePNG($im,"noir_et_blanc.png"); 
ImageDestroy($im);
?> 
        
        
       
      Toujours avec la même méthode, il est possible de coloriser l'image : 
      <?
...
$rouge=.299 * ($color['red'])+ .587 * ($color['green'])+ .114 * ($color['blue']);  $vert=.299 * ($color['red'])+ .587 * ($color['green'])+ .114 * ($color['blue']); $bleu=.100 * ($color['red'])+ .100 * ($color['green'])+ .100 * ($color['blue']); ImageColorSet($im, $i, $rouge, $vert, $bleu);
...
?>  
        
        
         | 
  
      |