La librairie GD (actuellement version 1.8.1) permet de créer
dynamiquement des images aux formats JPEG et PNG notamment (mais
plus au format GIF depuis la version 1.6, pour des problèmes
de droits). Elle est écrite en C (ANSI) et peut être
utilisée en PHP en compilant les sources du langage avec
l'option de configuration
--with-gd[=DIR]
où DIR est le répertoire des sources de GD.
Sous Windows, un fichier .dll (GD version 1.3 incluant donc le support
du GIF) est disponible.
Avec PHP4, il y a de fortes chances que GD soit utilisable après
une installation par défaut, sous Unix comme sous Windows.
GD est particulièrement intéressante pour réaliser
des graphes, en liaison avec une base de données
(l'un des points forts du PHP).
Création d'une image
La première chose à faire est d'indiquer au navigateur
le type de contenu (ici nous choisissons le format PNG),
puis de spécifier taille et couleurs de l'image (on utilise
la fonction ImageColorAllocate pour
allouer une couleur à notre image). Par exemple:
Header( "Content-type: image/png");
$image = imagecreate(300,300);
$rouge = ImageColorAllocate($image,255,0,0);
$vert = ImageColorAllocate($image,0,255,0);
$bleu = ImageColorAllocate($image,0,0,255);
$blanc = ImageColorAllocate($image,255,255,255);
$noir = ImageColorAllocate($image,255,255,255);
Nous allons ensuite "colorier" en noir notre image par:
ImageFilledRectangle($image,0,0,300,300,$noir);
Il est d'ores et déjà possible d'afficher le résultat
en écrivant:
ImagePNG($image);
ImageDestroy($image);
la seconde instruction servant à libérer la mémoire
réservée à l'image, mémoire devenue
inutile une fois que le résultat a été transmis
au navigateur.
Récupérer les données
d'une base pour créer un graphe
L'image précédente ne constitue que la toile de fond
de ce que nous voulons réaliser: un graphe représentant
une distribution de valeurs issues d'une base de données.
Nous prendrons l'exemple d'une base nommée "essai"
et contenant les données (arbitraires) suivantes:
Nous utiliserons MySQL pour gérer cette base.
Nous nommerons le tableau de valeurs "donnees" et nos
champs "id" (l'identifiant), "mois", "annee"
et "valeur".
Nous supposons la base déjà créée
et enrichie. En PHP, on s'y connectera par:
$connect = mysql_connect("localhost");
mysql_select_db("essai",$connect);
Puis on effectuera les requêtes suivantes:
$requete_sql = "SELECT MAX(valeur) FROM donnees";
$resultat_requete = $mysql_query($requete_sql,$connect);
$max= mysql_result($resultat_requete,donnees.valeur);
$requete_sql = "SELECT valeur FROM donnees WHERE annee='2001'
ORDER BY id";
$resultat_requete = mysql_query($requete_sql,$connect);
La première requête permet d'obtenir la valeur
maximale afin de dimensionner (calibrer) notre graphe. La
requête de type SELECT renvoie un identifiant à partir
duquel on peut récuperer le champ "valeur" du tableau
"donnees".
La seconde requête permet de récupérer les valeurs
de l'année 2001.
Il reste à traiter les données pour les présenter
sous forme de graphes. On utilise les fonctions de la librairie
BCMath (de même que pour GD, on doit compiler PHP en
incluant les sources de BCMath avec l'option
--enable-bcmath; sous Windows, l'extension est activée
par défaut en PHP4): bcmul (respectivement
bcdiv) multiplie (respectivement divise)
deux nombres passés en paramètres (le troisième
est la précision du calcul en nombre de décimales).
Ici, l'ordonnée est obtenue à partir de l'échelle
définie par notre valeur maximale: une valeur proche du maximum
a une ordonnée haute, une valeur très inférieure
une ordonnée faible (on utilise la formule: valeur*300/maximum).
Par ailleurs, le système de coordonnées manipulé
par GD à son origine au coin supérieur gauche du graphe:
on prendra garde à corriger l'ordonnée en conséquence.
On écrira donc en PHP:
$x=0; // origine des abscisses
$i=0; // compteur
while($colonne=mysql_fetch_array($resultat_requete))
{
$y
= bcmul(bcdiv($colonne[valeur],$max,2),300,2);
$points[$i][0] =
$x;
$points[$i][1] =
300-$y; // correction de l'ordonnée en prenant compte de
l'origine des coordonnées
$x+= 27.27; // 300
pixels de large et 12 valeurs (12 mois): l'incrément vaut
300/(12+1)=27.27
$i++;
}
puis les afficher (on relie les points par des lignes blanches):
for($i=0;$i<11;$i++) {
ImageLine($image,
$points[$i][0], $points[$i][1], $points[$i+1][0], $points[$i+1][1],
$blanc);
}
Il ne reste plus qu'à faire la même chose (dans une
autre couleur, par exemple le rouge) pour les valeurs de l'année
2000, et on obtient le résultat suivant (dont vous pouvez
télécharger
le code):
(Remarque: l'image a été convertie
au format GIF).
Pour plus d'informations sur GD, une documentation hélas
assez mal organisée existe, à l'adresse suivante:
http://www.boutell.com/gd.
|