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:
-
Génération d'images à partir d'un script shell, utilisant le
protocole CGI (gnuplot).
- Génération d'images directement à partir de PHP (JpGraph).
- 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> ...}
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.
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:
-
La génération automatique de limites d'échelle selon des
critères esthétiques (ça marche en général tout seul très bien).
- La gestion automatique d'un système de cache. En
effet, lorsqu'on demande une figure, si rien n'a changé elle n'est
pas régénérée mais sortie du cache. Pour le cas où un même script
crée des images différentes à la volée, ce mécanisme peut être
nuisible et doit être desactivé (quatrième argument de Graph
avec une valeur de -1).
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:
-
Non-map Projections
-
Cartesian Linear Projection (-Jx -JX)
- Logarithmic projection
- Power projection
- Geographical linear projection
- Linear Projection with Polar Coordinates (-Jp -JP)
- Conic Projections
-
Albers Conic Equal-Area Projection (-Jb -JB)
- Lambert Conic Conformal Projection (-Jl -JL)
- Equidistant Conic Projection (-Jd -JD)
- Azimuthal Projections
-
Lambert Azimuthal Equal-Area (-Ja -JA)
- Stereographic Equal-Angle Projection (-Js -JS)
- Orthographic Projection (-Jg -JG)
- Azimuthal Equidistant Projection (-Je -JE)
- Gnomonic Projection (-Jf -JF)
- Cylindrical Projections
-
Mercator Projection (-Jm -JM)
- Transverse Mercator (-Jt -JT)
- Universal Transverse Mercator UTM (-Ju -JU)
- Oblique Mercator (?-Jo -JO)
- Cassini Cylindrical Projection (-Jc -JC)
- Cylindrical Equidistant Projection (-Jq -JQ)
- General Cylindrical Projections (-Jy -JY)
- Miller Cylindrical Projections (-Jj -JJ)
- Miscellaneous Projections
-
Hammer Projection (-Jh -JH)
- Mollweide Projection (-Jw -JW)
- Winkel Tripel Projection (?-Jr -JR)
- Robinson Projection (-Jn -JN)
- Eckert IV and VI Projection (-Jk -JK)
- Sinusoidal Projection ?(-Ji -JI)
- Van der Grinten Projection (-Jv -JV)
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