PHP - Génération d'images

Décembre 2016

Prérequis

PHP permet de créer des images au format GIF à l'aide d'une librairie de fonctions prévue à cet effet. La librairie permettant de créer et manipuler des fichiers graphiques se nomme GD, ainsi, pour pouvoir utiliser ces fonctions il faut que PHP soit installé avec l'extension GD, c'est-à-dire passer le paramètre --with-gd.

La librairie de fonctions GD permet de créer assez facilement des fichiers au format GIF, en fonction par exemple de données stockées dans un SGBD (Système de gestion de bases de données). Il faut tout de même savoir que ce genre de procédé met à rude épreuve le processeur, il faut donc utiliser ces fonctions à bon escient (par exemple pour des diagrammes statistiques à barre, des graphiques sectoriels, ...).

Comment utiliser ces fonctions

Les fonctions de la librairies GD permettent de retourner une image, c'est-à-dire un fichier GIF. Ainsi un tel fichier ne peut envoyer du texte au navigateur, il doit obligatoirement être appelé à partir d'une page HTML (généralement avec une balise <IMG src="mon_fichier.php">).

D'autre part, pour que le navigateur sache qu'il s'agit d'un fichier de type GIF, la premiere chose à faire (avant d'envoyer n'importe quelle autre information au navigateur) est d'envoyer un en-tête HTTP indiquant le type MIME du fichier, c'est-à-dire :

 headers("Content-Type: image/gif");



La principale fonction de la librairie est imagegif() elle permet de retourner au navigateur l'image créée avec les autres fonctions, en passant en paramètres un entier identifiant l'image. Si jamais le nom du fichier est passé en second argument, le fichier est écrit sur le disque.

 booléen imagegif(entier image, chaîne NomDuFichier);



  • La fonction imagegif() ne fonctionne pas avec PHP4
  • Notez que vous pouvez utiliser imagepng() et imagejpg()!


La fonction imagecreate() permet de créer un identifiant pour une image vierge possédant les dimensions indiquées en paramètres.

 entier imagecreate(entier largeur,entier hauteur);




La fonction imagecreatefromgif() permet de créer un
identifiant pour l'image créée à partir d'une image GIF existant sur le disque,
en passant en paramètre le nom du fichier.

 entier createimagefromgif(chaîne NomDuFichier);



Enfin la fonction imagedestroy() permet de vider la mémoire allouée
à l'image dont on a passé l'identifiant en paramètre.

 booléen imagedestroy(entier image);


Voilà donc un script minimal (et inutile) créant une image PHP
à partir d'une image présente sur le disque :

<?php
headers("Content-Type: image/gif");

$image = imagecreatefromgif("toto.gif");

imagegif($image);

?>

L'allocation de couleur

La majeure partie des fonctions de la librairie GD permettent de créer une image,

  • en dessinant des formes (trait, rectangle, cercle, ...)
  • en allouant des couleurs à l'image
  • en dessinant des chaînes de caractères
  • ...




La plupart des fonctions graphiques nécessitent le passage en paramètre
d'une couleur. Ainsi, PHP fournit des fonctions permettant d'allouer une couleur à

une image en spécifiant les composantes RGB (Red, Green, Blue soient Rouge,
Vert et Bleu
) de la couleur.


La fonction imagecolorallocate() alloue une
couleur à une image en spécifiant ses composantes RGB sous forme entière
(0 à 255 pour chaque composante), ou hexadécimale (0x00 à 0xFF pour chaque
composante).

 entier imagecolorallocate(entier image, entier rouge,entier vert, entier bleu);


Voici quelques exemples d'allocation de couleurs avec cette fonction (avec les composantes en hexadécimal ou en entier) :

$noir = imagecolorallocate($image,0,0,0);

$rouge = imagecolorallocate($image,255,0,0);

$vert = imagecolorallocate($image,0,0xFF,0);

La création de formes

La librairie GD fournit un panel de fonctions permettant de créer des formes
primaires telles que :

  • des rectangles
  • des ellipses (donc des cercles)
  • des arcs
  • des lignes


Généralement ces fonctions admettent en premier paramètre l'identifiant
de l'image dans laquelle la forme doit être créée, puis les coordonnées
permettant de générer la forme, et enfin la couleur de l'élément.
Elles retournent 1 si l'élément a pu être dessiné, 0 dans le cas contraire

Voici un tableau présentant les fonctions de génération de forme :



FonctionDescription
imagearc(entier image,entier x,entier y,entier largeur,entier hauteur,entier début,entier fin,entier couleur)Crée un arc de centre (x,y) dont la largeur et la hauteur sont en pixels. Début et fin représentent les angles
de début et de fin (le degré 0 est à trois heures) en tournant dans le sens des aiguilles d'un montre
imagedashedline(entier image,entier xdebut,entier ydebut,entier xfin,entier yfin,entier couleur)Trace un trait pointillé entre les points (xdebut,ydebut) et (xfin,yfin) de la couleur spécifiée
imagefilledpolygon(entier image,tableau coordonnees,entier nonbre,entier couleur)Crée un polygone de la couleur spécifiée, dont les points sont stockes dans un tableau de valeurs (x,y). Le nombre de points du tableau
à utiliser est spécifié en paramètre nombre
imagefilledrectangle(entier image,entier xgauchehaut,entier ygauchehaut,entier xdroitebas,entier ydroitebas,entier couleur)Crée un rectangle rempli avec la couleur spécifiée, et dont les coins supérieur gauche et inférieur droit sont spécifiés en argument
imageline(entier image,entier xdebut,entier ydebut,entier xfin,entier yfin,entier couleur)Trace un trait entre les points (xdebut,ydebut) et (xfin,yfin) de la couleur spécifiée
imagepolygon(entier image,tableau coordonnees,entier nonbre,entier couleur)Crée un polygone non rempli dont le contour est de la couleur spécifiée, dont les points sont stockes dans un tableau de valeurs (x,y). Le nombre de points du tableau
à utiliser est spécifié en paramètre nombre
imagerectangle(entier image,entier xgauchehaut,entier ygauchehaut,entier xdroitebas,entier ydroitebas,entier couleur)Crée un rectangle nom rempli dont le contour est de la couleur spécifiée, et dont les coins supérieur gauche et inférieur droit sont spécifiés en argument




Voici un exemple montrant comment créer des formes simples avec PHP :

<?php
$image = imagecreate(160,100);

$fond = imagecolorallocate($image,0xEF,0xF2,0xFB);

$noir = imagecolorallocate($image,0,0,0);

imagefill($image,0,0,$fond);

imagefilledpolygon($image,array(80,15,45,85,125,85),3,$noir);

header("Content-Type: image/gif");

imagegif($image);

?>


Deux fonctions supplémentaires vous permettront de remplir une zone avec
une couleur :



FonctionDescription
imagefill(entier image,entier x,entier y,entier couleur)Remplit une zone d'une même couleur par la couleur spécifiée en argument,
en commençant le remplissage à partir du point indiqué en paramètre
imagetoborder(entier image,entier x,entier y,entier couleurbordure,entier couleur)Remplit une zone délimitée par une bordure d'une couleur, par la couleur spécifiée en argument,
en commençant le remplissage à partir du point indiqué en paramètre

Les chaînes de caractères

PHP permet d'autre part de dessiner des chaînes de caractères dans une image
grâce à une grande variété de fonctions dédiées.
Cela autorise ainsi la création de légendes ou de boutons dynamiques, en fonction
du texte passé en paramètre, stocké dans un fichier, ou bien dans une base de données.


La principale fonction permettant de créer des chaînes de caractères dans l'image
est imagestring() :

 booléen imagestring(entier image,
entier police,
entier x,
entier y,
chaine texte,
entier couleur);


Cette fonction permet de créer une chaîne de caractères contenant le texte passé

en argument à la position spécifiée par les arguments (x,y) avec la police indiquée.

En réalité PHP propose 5 polices par défaut numérotées de 0 à 5,
mais il est possible de spécifier une police p[ersonnalisée grâce à la fonction

imageloadfont() :

 Entier imageloadfont(chaîne Nom_du_Fichier);



Le format du fichier de police passé en paramètre peut varier selon le système sur lequel
PHP fonctionne...


Enfin, les fonctions imagefontwidth() et imagefontheight() renvoient
la largeur et la hauteur de la police passée en unique paramètre. Ainsi, il est facile de connaître
le nombre de pixels que va occuper la chaîne entière :

 $largeur = imagefontwidth($police) * strlen($text);

$hauteur = imagefontheight($police);




Voici un tableau présentant les fonctions de création de chaînes de
caractères graphiques :



FonctionDescription
booléen imagechar(entier image,entier police,entier x,entier y,chaîne caractere,entier couleur)Crée un caractère à l'emplacement (x,y) (position de l'angle supérieur gauche du caractère). La police du caractère
peut-être choisie parmi les polices par défaut (1 à 5) ou bien une police personnalisé que vous avez ouvert précédemment
avec imageloadfont()
booléen imagecharup(entier image,entier police,entier x,entier y,chaîne caractere,entier couleur)Crée un caractère orienté à l'horizontale (rotation de 90°) à l'emplacement (x,y) (position de l'angle supérieur gauche du caractère). La police du caractère
peut-être choisie parmi les polices par défaut (1 à 5) ou bien une police personnalisé que vous avez ouvert précédemment
avec imageloadfont()
entier imagefontheight(entier police)retourne la hauteur de la police utilisée
entier imagefontwidth(entier police)retourne la largeur de la police utilisée
entier imageloadfont(chaîne nom_du_fichier)Charge la police dont le nom est passé en argument et retourne son identifiant
booléen imagestring(entier image,entier police,entier x,entier y,chaîne texte,entier couleur)Crée une chaîne de caractères à l'emplacement (x,y) (position de l'angle supérieur gauche de la chaîne de caractère). La police du caractère
peut-être choisie parmi les polices par défaut (1 à 5) ou bien une police personnalisé que vous avez ouvert précédemment
avec imageloadfont()
booléen imagestringup(entier image,entier police,entier x,entier y,chaîne texte,entier couleur)Crée une chaîne de caractères orientée verticalement (rotation de 90°) à l'emplacement (x,y) (position de l'angle supérieur gauche de la chaîne de caractère). La police du caractère
peut-être choisie parmi les polices par défaut (1 à 5) ou bien une police personnalisé que vous avez ouvert précédemment
avec imageloadfont()

Un diagramme des navigateurs de vos visiteurs

Le script suivant est fourni par le webmaster de C'est quoi Linux. Il vous permet
de créer une image contenant un diagramme circulaire des navigateurs de vos visiteurs, sachant que ceux-ci
sont stockés dans une table appelée visiteurs dans un champ nommé navigateur.

Pour stocker ces valeurs, il suffit de créer cette table sur votre site, puis de stocker la valeur
à l'aide de la requête suivante :

INSERT INTO visiteurs values("$HTTP_USER_AGENT")


Voici le code PHP :

<?
header("Content-type: image/gif");

$host="votre.base.de.donnees";

$user="votre.login";

$pass="votre.mot.de.passe";

$bdd="nom_de_la_base";

mysql_connect($host,$user,$pass);

mysql_select_db($bdd);

$query="SELECT navigateur FROM visiteurs";

$result=mysql_query($query);

$netscape3=0;

$netscape4=0;

$ie3=0;

$ie4=0;

$ie5=0;

$autre=0;

while($row=mysql_fetch_row($result))
{

$total++;

if(ereg("3(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
{
$netscape3++;

}
if(ereg("4(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
{
$netscape4++;

}
if(ereg("MSIE(\_?)( ?)3",$row[0]) )
{
$ie3++;

}
if(ereg("MSIE(\_?)( ?)4",$row[0]) )
{
$ie4++;

}
if(ereg("MSIE(\_?)( ?)5",$row[0]) )
{
$ie5++;

}
if( (!ereg("3(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
&&(!ereg("4(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
&&(!ereg("MSIE(\_?)( ?)3",$row[0]) )
&&(!ereg("MSIE(\_?)( ?)4",$row[0]) )
&&(!ereg("MSIE(\_?)( ?)5",$row[0]) ))
{
$autre++;

}
}

mysql_close();

function compare($navig,$nbre)
{

if($navig==$netscape3) { $navig++; }
if($nbre!=1)
{
if($navig==$netscape4) { $navig++; }
}
if($nbre>2)
{
if($navig==$ie3) { $navig++; }
}
if($nbre>3)
{
if($navig==$ie4) { $navig++; }
}
if($nbre>4)
{
if($navig==$ie5) { $navig++; }
}
return($navig);

}

$netscape3=$netscape3*10;

$netscape4=$netscape4*10;

$ie3=$ie3*10;

$ie4=$ie4*10;

$ie5=$ie5*10;

$autre=$autre*10;

$netscape4=compare($netscape4,1);

$ie3=compare($ie3,2);

$ie4=compare($ie4,3);

$ie5=compare($ie5,4);

$autre=compare($autre,5);

function radians($degrees)
{

return($degrees * (pi()/180.0));

}

function circle_point($degrees, $diameter)
{

$x = cos(radians($degrees)) * ($diameter/2);

$y = sin(radians($degrees)) * ($diameter/2);

return(array($x,$y));

}

$ChartDiameter = 130;

$ChartFont = 2;

$ChartFontHeight = imagefontheight($ChartFont);

$ChartFontWidth = imagefontwidth($ChartFont);

$ChartData = array($netscape3,$netscape4,$ie3,$ie4,$ie5,$autre);

$ChartData2 = array($netscape3=>"Netscape 3",
$netscape4=>"Netscape 4",
$ie3=>"Internet Exploreur 3",
$ie4=>"Internet Exploreur 4",
$ie5=>"Internet Exploreur 5",
$autre=>"Autres Navigateurs");

$ChartWidth = $ChartDiameter + 20 + ($ChartFontWidth * 40);

$ChartHeight = $ChartDiameter + 20;

rsort($ChartData);

arsort($ChartData2);

$ChartCenterX = $ChartDiameter/2 + 10;

$ChartCenterY = $ChartDiameter/2 + 10;

$image = imagecreate($ChartWidth, $ChartHeight);

$colorBody = imagecolorallocate($image,0xEF,0xF2,0xFB);

$colorBorder = imagecolorallocate($image,0x00,0x00,0x00);

$colorText = imagecolorallocate($image,0x00,0x00,0x00);

$colorSlice[]= imagecolorallocate($image,0x76,0x89,0xFF);

$colorSlice[]= imagecolorallocate($image,0x96,0xA6,0xFF);

$colorSlice[]= imagecolorallocate($image,0xA6,0xB9,0xFF);

$colorSlice[]= imagecolorallocate($image,0xB6,0xC9,0xFF);

$colorSlice[]= imagecolorallocate($image,0xC6,0xD9,0xFF);

$colorSlice[]= imagecolorallocate($image,0xD6,0xE9,0xFF);

imagefill($image,0,0,$colorBody);

$Degrees = 0;

for($index=0; $index < count($ChartData); $index++)
{

$ChartDataReel=(int)($ChartData[$index]/10);

if( $ChartDataReel !=0)
{
$StartDegrees = round($Degrees);

$Degrees+= (($ChartDataReel/$total)*360);

$EndDegrees = round($Degrees);

$CurrentColor = $colorSlice[$index%(count($colorSlice))];

imagearc($image, $ChartCenterX, $ChartCenterY, $ChartDiameter,
$ChartDiameter, $StartDegrees, $EndDegrees, $CurrentColor);

list($ArcX, $ArcY) = circle_point($StartDegrees, $ChartDiameter);

imageline($image, $ChartCenterX, $ChartCenterY,
floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY), $CurrentColor);

list($ArcX, $ArcY) = circle_point($EndDegrees, $ChartDiameter);

imageline($image, $ChartCenterX, $ChartCenterY,
floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY), $CurrentColor);

$MidPoint = round((($EndDegrees - $StartDegrees)/2) + $StartDegrees);

list($ArcX, $ArcY) = circle_point($MidPoint, $ChartDiameter/2);

imagefilltoborder($image, floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY), $CurrentColor, $CurrentColor);

}
}

imagearc($image, $ChartCenterX, $ChartCenterY, $ChartDiameter,
$ChartDiameter, 0, 360, $colorBorder);

for($index=0; $index < count($ChartData); $index++)
{

$CurrentColor = $colorSlice[$index%(count($colorSlice))];

$LineX = $ChartDiameter + 20;

$LineY = 30 + ($index*($ChartFontHeight + 2));

imagerectangle($image, $LineX, $LineY, $LineX +
$ChartFontHeight, $LineY + $ChartFontHeight, $colorBorder);

imagefilltoborder($image, $LineX + 2,
$LineY + 2, $colorBorder, $CurrentColor);

$valeur=(int)($ChartData[$index]/10);

$valeur2=$ChartData[$index];

$pourcentage=round(($valeur/$total)*100);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight,
$LineY, "$ChartData2[$valeur2]", $colorText);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight+
23*$ChartFontWidth, $LineY, "$valeur", $colorText);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight+
31*$ChartFontWidth, $LineY, "$pourcentage %", $colorText);

}

imagegif($image);

?>

A voir également :

Ce document intitulé «  PHP - Génération d'images  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.