Previous Up Next

Chapter 14  Génération dynamique d'images

On verra trois paquetages qui permet de générer des images très utilisées dans le monde scientifique: graphiques de données numériques (tracés de courbes XY, de camemberts,...) et dessins de données sur fonds de cartes géographiques.

Trois approches différents sont proposés:
  1. Génération d'images à partir d'un script shell, utilisant le protocole CGI (gnuplot).
  2. Génération d'images directement à partir de PHP (JpGraph).
  3. Génération d'images commandés à partir de PHP en utilisant un script CGI (GMT).
Un petit rappel: Toutes les images incluses doivent exister en tant que URL à part: soit des fichiers images existants, soit des images générées à la volée par des scripts CGI. Ceci se fait en utilisant <img src="image" border=0 align=center width=300 height=200> où il est fortement recommandé de renseigner la taille de l'image, ceci pour permettre au navigateur de terminer le formattage du document en laissant l'espace nécessaire à l'affichage de l'image, sans attendre son chargement. En pratique, cela veut dire qu'une personne peut commencer à lire le contenu d'une page avant que toutes les images soient chargées.

14.1  Génération de graphiques avec Gnuplot (shell CGI)

Gnuplot est un traceur de courbes 2D/3D disponible sur de nombreuses plateformes. L'interface est rudimentaire (commandes en ligne), mais simple à retenir, et assez puissante pour permettre le dépouillement presque en temps réel de vos résultats de calcul. Les instructions se transmettent en ligne de commande ou avec un fichier script. Il est possible de tracer des fonctions ou des fichiers de points. Ce mécanisme de création d'images avec des fichiers de script et celui qui permet l'automatisation de la procédure dans un script CGI.

14.1.1  Format de sortie

Gnuplot génère ses images sur le terminal de sortie défini. Par défaut, ce sera une fenêtre controlée par votre gestionnaire de fenêtres (e.g. X11 sous unix). Pour créer un fichier, il faut par contre lui dire de générer l'image sous un autre format. Ceci se fait avec l'instruction set terminal xxx. Où xxx est en général png (Portable Network Graphics) pour l'affichage sur le web (le gif n'est pas supporté en sortie). Cependant, pour déboguer des scripts gnuplot, il est intéressant de laisser l'affichage par défaut, pour voir directement ce qui se passe.

14.1.2  Commandes de génération d'images

Trois commandes permettent de générer des images sous gnuplot:plot, splot et replot.

plot permet de travailler en coordonnées polaires ou rectangulaires (set polar et set no polar respectivement.
      plot {<ranges>}
            {<function> | {"<datafile>" {datafile-modifiers}}}
            {axes <axes>} {<title-spec>} {with <style>}
            {, {definitions,} <function> ...}
splot permet de dessiner des surfaces et des contours en plus des lignes et points.
      splot {<ranges>}
             <function> | "<datafile>" {datafile-modifiers}}
             {<title-spec>} {with <style>}
             {, {definitions,} <function> ...}

14.1.3  Exemples

La génération d'un graphique de la fonction cosinus(x) peut se faire très facilement avec gnuplot avec le script shell de l'exemple 1
Exemple 1  

#!/bin/bash
gnuplot <<EOF
set term png color
set output 'cos.png'
plot cos(x)
EOF

Des graphiques bien plus compliqués peuvent être fait très simplement, comme les surfaces 3D des exemples 2 et 3 qui génèrent les figures 14.1 et 14.2.
Exemple 2  

#!/bin/bash
gnuplot << EOF
set terminal png color
set output 'surface.png'
set title "z = sin(x^2 + y^2) / (x^2 + y^2)",+5
set hidden3d
set isosamples 60
set view 42,40
set nocontour
set xrange [-3:3]
set yrange [-3:3]
splot sin(x*x + y*y) / (x*x + y*y)
EOF

Exemple 3  

#!/bin/bash
# TORES
gnuplot << EOF
set terminal png color
set output 'tores.png'
set tics
set ticslevel 0.1
set grid
set border 31 lt 5
set parametric
set autoscale
set hidden
set nokey
set noclip
set title "TORES",+5
set urange [-pi:pi]
set vrange [-pi:pi]
set zrange [-1.5:+1.5]
set isosamples 60,30
set view 45,30,0.9,1.8
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with lines,\
1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with lines
EOF

A noter que ce type de traitement peut être fait très facilement à partir de données qui se trouvent sur un fichier (en général un fichier temporaire, dont le nom est passé en paramètre). Pour les applications web, cette solution marche bien, le seul piège à éviter est d'écraser un fichier avec un autre dans le cas de visualisation simultané par plusieurs utilisateurs.


Figure 14.1: Images générées par gnuplot




Figure 14.2: Images générées par gnuplot


Pour générer une application CGI on peut se passer de la création d'un fichier temporaire, en envoyant la sortie directement vers le navigateur. En reprennant l'exemple des tores 4.
Exemple 4  

#!/bin/bash
# TORES
echo "Content-type: image/png"
echo ""
gnuplot << EOF
set terminal png color
set tics
set ticslevel 0.1
set grid
set border 31 lt 5
set parametric
set autoscale
set hidden
set nokey
set noclip
set title "TORES",+5
set urange [-pi:pi]
set vrange [-pi:pi]
set zrange [-1.5:+1.5]
set isosamples 60,30
set view 45,30,0.9,1.8
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with lines,\
1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with lines
EOF

14.2  Génération de graphiques avec JpGraph (PHP)

Il est possible, en PHP, d'utiliser des briques logicielles développées par d'autres personnes. La principale librairie concernant la création de graphiques est la librairie JpGraph. C'est une librairie objet permettant de créer des graphiques avec un minimum de code. La JpGraph assigne des valeurs par défaut logiques ce qui vous permet de créer des graphiques tres complexes avec très peu de code. Parmi les principales caractéristiques : Supporte le formats JPEG, PNG, GIF. Propose différents types de graphiques : line-plots, filled line-plots, accumulated line-plots, bar plots, accumulated bar plots, grouped bar plots, scatter plots, impuls plots, spider (a.k.a. Web) plots and pie charts. Gère un module de cache permettant de minimiser l'utilisation du temps processeur. Gère l'antialiasing des lignes. L'auteur de cette librarie est Johan Persson ([email protected]) La première release publique date de fevrier 2001. Cette librairie est sous licence GPL2.

14.2.1  Utilisation

La librairie va automatiquement générer les headers à envoyer au navigateur. Pour utiliser la librairie vous allez devoir inclure au moins deux fichiers, la librairie de base et une ou plusieurs extensions. Prenons l'exemple ou nous voudrions utiliser les lignes, vous devez inclure en haut de votre fichier PHP les lignes suivantes :
     <?
     include ("jpgraph.php");
     include ("jpgraph_line.php");
     . . .
     // Code utilisant la lib JPGraph     
     ?>
La règle d'utilisation est simple: on crée un graphique du type souhaité, on définit les options et paramètres voulus, et on appelle stroke pour générer le fichier proprement dit.

Parmi les types connus: spider-plots, pie-charts, scatter-plots, line-plots, filled line-plots, accumulated line- plots, bar plots, accumulated bar plots, grouped bar plots, error plots, line error plots et graphiques de Gantt.

Deux caractéristiques méritent attention spéciale:

14.2.2  Exemples

Le graphique le plus simple est le lineplot, comme dans l'exemple 5.
Exemple 5  

     <?
     include ("jpgraph.php");
     include ("jpgraph_line.php");
     // Il faut mettre des valeurs dans un tableau.
     // Vous pouvez les recuperer d'une base de données ou autres...
     $ydata = array(6,5,25,12,5,10,32,13,5,21);
     // On créé l'objet Graph. Ces deux appels sont toujours necessaires.
     $graph = new Graph(300,200);    
     $graph->SetScale("textlin");
     // On créé un tracé 
     $lineplot=new LinePlot($ydata);
     // On ajoutte ce tracé au graph
     $graph->Add($lineplot);
     // On affiche le graphique
     $graph->Stroke();
     ?>

Il génère l'image de la figure 14.3


Figure 14.3: Lineplot généré par JpGraph


On peut créer facilement des camemberts en utilisant le code de l'exemple 6.
Exemple 6  

     <?php
     include ("jpgraph.php");
     include ("jpgraph_pie.php");
     // Some data
     $data = array(40,21,17,14,23);
     // Create the Pie Graph. Note you may cach this  by adding the
     // ache file name as PieGraph(300,300,"SomCacheFileName")
     $graph = new PieGraph(300,200);
     $graph->SetShadow();
     // Set A title for the plot
     $graph->title->Set("Example 1 Pie plot");
     $graph->title->SetFont(FF_FONT1,FS_BOLD);
     // Create graph
     $p1 = new PiePlot($data);
     $graph->Add($p1);
     // .. and finally stroke it
     $graph->Stroke();
     ?>

Il génère l'image de la figure 14.4


Figure 14.4: Camembert généré par JpGraph


Une version en 3D peut être créé avec le code de l'exemple 7.
Exemple 7  

     <?php
     include ("../jpgraph.php");
     include ("../jpgraph_pie.php");
     include ("../jpgraph_pie3d.php");
     // Some data
     $data = array(20,17,15,20,15,25,25,10);
     // Create the Pie Graph.
     $graph = new
     PieGraph(350,200,"pieex1");
     $graph->SetShadow();
     // Set A title for the plot
     $graph->title->Set("Example 1 3D Pie
     plot");
     $graph->title->SetFont(FF_VERDANA,FS_BOLD,18);
     $graph->title->SetColor("darkblue");
     $graph->legend->Pos(0.1,0.2);
     // Create 3D pie plot
     $p1 = new PiePlot3d($data);
     $p1->SetTheme("sand");
     $p1->SetCenter(0.4);
     $p1->SetAngle(50);
     $p1->SetFont(FF_TIMES,FS_NORMAL,14);
     $p1->SetLegends(array("Jan","Feb","Mar","Apr",
     "May","Jun","Jul","Aug","Sep","Oct"));
     $graph->Add($p1);
     $graph->Stroke();
     ?>

Il génère l'image de la figure 14.5


Figure 14.5: Camembert 3D généré par JpGraph


14.3  Génération d'images géographiques avec GMT (PHP/CGI)

GMT est l'oeuvre de Paul Wessel de l'Université de Hawaii. Sa popularité est due au prix (gratuit !) mais aussi à sa flexibilité du fait d'être piloté par la ligne de commandes, pouvant donc utiliser des scripts génériques de création d'images PostScript de haute qualité.

14.3.1  Options standard

La force de GMT c'est qu'on peut tout contrôler depuis la ligne de commande. Le malheur, c'est qu'il y a beaucoup de choses à controler. Ainsi, il y a toute une famille d'options de ligne de commande standard qui sont très souvent utilisés et qui indiquent typiquement la région d'intérêt, la résolution, les unités et le type de projection.
Option Meaning
-B Defines tickmarks, annotations, and labels for basemaps and axes
-H Specifies that input tables have header record(s)
-J Selects a map projection or one of several non-map projections
-K Allows more plot code to be appended to this plot later
-O Allows this plot code to be appended to an existing plot
-P Selects Portrait plot orientation [ Default is landscape]
-R Defines the min. and max. coordinates of the map/plot region
-U Plots a time-stamp, by default in the lower left corner of page
-V Verbose operation
-X Sets the x-coordinate for the plot origin on the page
-Y Sets the y-coordinate for the plot origin on the page
-c Specifies the number of plot copies
-: Input geographic data are (lat,lon) rather than (lon,lat)

Le nombre de type de projections est énorme:
  1. Non-map Projections

  2. Conic Projections

  3. Azimuthal Projections

  4. Cylindrical Projections

  5. Miscellaneous Projections

14.3.2  Exemples

La force de GMT est la génération de figures en format PostScript. Pour le web il faut forcément les convertir à un format plus populaire. Pour cela, on peut utiliser l'utilitaire «convert qui est fourni avec ImageMagick, par exemple, et ainsi générer des fichier PNG ou GIF.

Le code, très lisible (...), ... de l'exemple 8 créé une image spectaculaire.
Exemple 8  

gmtset HEADER_FONT_SIZE 30 OBLIQUE_ANOTATION 0 DEGREE_FORMAT 0
makecpt -Crainbow -T-2/14/2 >! g.cpt
grdimage HI_geoid2.grd -R160/20/220/30r -JOc190/25.5/292/69/4.5i -E50 -K -P -B10 -Cg.cpt \
   -U/-1.25i/-1i/"Example 2 in Cookbook" -X1.5i -Y1.25i >! example_02.ps
psscale -Cg.cpt -D5.1i/1.35i/2.88i/0.4i -O -K -L -B2:GEOID:/:m: -E >> example_02.ps
grd2cpt HI_topo2.grd -Crelief -Z >! t.cpt
grdgradient HI_topo2.grd -A0 -Nt -GHI_topo2_int.grd
grdimage HI_topo2.grd -IHI_topo2_int.grd -R -JO -E50 -B10:."H@#awaiian@# T@#opo and @#G@#eoid:" -O -K \
   -Ct.cpt -Y4.5i >> example_02.ps
psscale -Ct.cpt -D5.1i/1.35i/2.88i/0.4i -O -K -I0.3 -B2:TOPO:/:km: >> example_02.ps
cat << EOF | pstext -R0/8.5/0/11 -Jx1i -O -N -Y-4.5i >> example_02.ps
-0.4 7.5 30 0.0 1 2 a)
-0.4 3.0 30 0.0 1 2 b)
EOF
\rm -f .gmtcommands HI_topo2_int.grd ?.cpt

Il génère l'image de la figure 14.6


Figure 14.6: Topographie et géoide de Hawaii


Une surface mathématique comme celle générée avec gnuplot peut être faite beaucoup plus joliment:
Exemple 9  

grdmath -R-15/15/-15/15 -I0.3 X Y HYPOT DUP 2 MUL PI MUL 8 DIV COS EXCH NEG 10 DIV EXP MUL \
   = sombrero.grd
echo '-5    128    5    128' >! gray.cpt
grdgradient sombrero.grd -A225 -Gintensity.grd -Nt0.75
grdview sombrero.grd -JX6i -JZ2i -B5/5/0.5SEwnZ -N-1/255/255/255 -Qs -Iintensity.grd -X1.5i -K \
   -Cgray.cpt -R-15/15/-15/15/-1/1 -E120/30 -U/-1.25i/-0.75i/"Example 5 in Cookbook" >! example_05.ps
echo "4.1 5.5 50 0 33 2 z(r) = cos (2@~p@~r/8) * e@+-r/10@+" | pstext -R0/11/0/8.5 -Jx1i -O \
   >> example_05.ps
\rm -f gray.cpt sombrero.grd intensity.grd .gmtcommands

Il génère l'image de la figure 14.7


Figure 14.7: Surface mathématique


Et pèle-mèle, mille autre types de figures, de la figure 14.8 à la figure 14.11.


Figure 14.8: Distribution sur fond géographique




Figure 14.9: Triangulation de Délaunay




Figure 14.10: Clipping d'images




Figure 14.11: Champs vectoriels



Previous Up Next