fire.gif

DISEGNARE CON PHP3
L'integrazione della libreria grafica GD trasforma PHP in un tool completo per la creazione di immagini e file grafici. Si tratta di una funzionalità davvero curiosa ma utile soprattutto nel caso in cui si debbano disegnare diagrammi statistici
Immaginiamo di dover rappresentare graficamente una serie di dati numerici. Abbiamo realizzato alcune statistiche ed ora vogliamo pubblicarle direttamente sia sulla Intranet aziendale e sia su Internet in modo da raggiungere un pubblico più vasto. Oltre alle tabelle piene di numeri sorge la necessità di realizzare una serie di grafici per rendere la visualizzazione dei nostri calcoli più significativa. Poiché i dati sono estremamente variabili e le statistiche devono essere generate in tempo reale, consentendo quindi a qualsiasi utente in qualsiasi momento di leggerle o stamparle, si è deciso di rinunciare alla classica pubblicazione via ftp di una serie di pagine html preconfezionate. A prima vista il compito non sembra uno dei più facili. Ed invece il nostro server Linux con l'accoppiata Apache-PHP3 ci aiuterà nel superare l'apparente complessità del problema. Avremo soltanto bisogno delle numerose funzioni matematiche native di php e dei comandi per la generazione delle primitive grafiche messi a disposizione dalla libreria grafica GD.
linea.gif
LA LIBRERIA GD
Si tratta di un'insieme di funzioni scritte in linguaggio C, facilmente riutilizzabili, appositamente sviluppate per facilitare la generazione di punti, linee, poligoni ed archi. I formati grafici supportati sono il gif, il jpeg, il png ed il gd. Mentre per i primi tre è stato sviluppato un algoritmo di compressione specifico per il quarto, invece, non si sono adottate tecnche di programmazione basate sugli standard grafici attuali. Il formato proprietario gd è stato creato solo per motivi di efficienza. Infatti il caricamento di immagini di grosse dimensioni, preventivamente salvate in tale fomato, risulta molto più veloce rispetto all'apertura dei tradizionali file gif o jpg. La versione aggiornata della libreria, creata da Thomas Boutell, è la 1.3. Dopo averla scaricata gratuitamente dal sito http://www.boutell.com/gd potremo utilizarne le funzioni in qualsisi progetto, sia commerciale che no-profit. Per consentire ad uno script php3 di creare su file oppure al volo, direttamente sulla pagina del browser, figure e grafici, si dovrà includere la libreria gd nel linguaggio php mediante un'opportuna istruzione di linking . Supponendo di aver compilato e copiato i sogenti di GD nella directory /usr/lib/gd del server Linux, il parametro da fornire al comando configure, prima di avviare le istruzioni di make per la complilazione e l'installazione del pacchetto php, sarà

--with-gd=/usr/lib/gd

A questo punto, dato che tutto è stato installato correttamente, passimo alla presentazione delle principali funzioni grafiche.
linea.gif
LE FUNZIONI GRAFICHE
Le funzioni della libreria gd operano su oggetti definiti come strutture del linguaggio C. In altre parole le entità fondamentali di gd, immagini e fonts, non sono altro che dati di tipo struttura (struct). In questo modo si spiega il motivo per cui tutte le funzioni grafiche restituiscono o richiedono un puntatore a tali strutture. In php, tuttavia, il termine puntatore, tipico del C, cambia e si trasforma in identificatore. Per creare una nuova immagine, per esempio larga 400 ed alta 300 pixel, si usa questa istruzione

$img = imagecreate(400, 300);

dove $img non è altro che l'dentificatore dell'immagine, mentre 400 e 300 sono le dimensioni in pixel della figura, rispettivamente largezza ed altezza: due dati di tipo intero (integer). A questo punto possiamo attribuire un colore di sfondo all'immagine con la funzione imagecolorallocate()

$bianco = imagecolorallocate($img, 255, 255, 255);

che richiede come parametri l'identificatore dell'immagine e i valori RGB del colore scelto, ovvero le quantità dei tre colori primari: rosso, verde e blu. Dopo aver creato questa sorta di foglio da disegno possiamo iniziare a dar libero sfogo alla nostra fantasia disegnando alcune fgure. Iniziamo da un cerchio di raggio 100 pixel con il contorno nero. Prima si definisce il colore e poi si disegna:

$nero = imagecolorallocate($img, 0, 0, 0);
imagearc($img, 200, 150, 100, 100, 0, 360, $nero);

Il realtà la funzione imagearc() è stata ideata per tracciare archi. Però, assegnando particolari valori ai parametri, si possono disegnare anche ellissi e cerchi. Oltre al consueto identificatore la funzione richiede nell'ordine i seguenti argomenti: coordinate x e y del centro dell'arco, larghezza ed altezza degli assi dell'arco (può essere cosiderato una ellissi parziale), inizio e fine dell'arco entrambi specificati in gradi sessagesimali, il colore di contorno. Che ne dite se provassimo a riempire il cerchio di nero? Facile, basta usare la funzione imagefill() e passarle le coordinate di un punto interno al cerchio.

imagefill($img, 200, 150, $nero);

Ora possiamo salvare tutto il disegno scrivedo il file cerchio.gif una directory di pubblicazione del server web con quest'ultima funzione

imagegif($img, "/www/prove/cerchio.gif");

Se invece volessimo far apparire l'immagine direttamente su Netscape dovremmo usare, subito all'inizio dello script, una istruzione per inviare una intestazione http al server web e poi la funzione imagegif() senza il secondo parametro. In quest'ultimo caso il programma avrebbe questa forma


<?php
  Header("Content-type: image/gif");
  $img = imagecreate(400, 300);
  $bianco = imagecolorallocate($img, 255, 255, 255);
  $nero = imagecolorallocate($img, 0, 0, 0);
  imagearc($img, 200, 150, 100, 100, 0, 360, $nero);
  imagefill($img, 200, 150, $nero);
  imagegif($img);
?>

Un'ultima osservazione. Attenzione a non scrivere codice html o php3 prima della funzione header() e del marcatore <?php, e dopo la funzione imagegif() ed il tag ?>. I risultati sarebbero imprevedibili.
linea.gif
UN ESEMPIO PRATICO
Uno dei comandi più utili di Linux è "df". Sicuramente è anche uno dei più usati poiché a furia di installare software si deve continuamente tenere sotto controllo lo stato del disco. df infatti stampa alcune informazioni sui filesystem montati nel sistema, visualizzando per ognuno di essi lo spazio totale, usato e disponibile. Per testare la flessibilità di php e della libreria gd abbiamo pensato di usare il comando df con un browser ottenendo una rappresentazione grafica dei risultati. Nel nostro pc di prova il comando df stampa le seguenti righe

img_articolo

Lo script df.php3 dovrà intabellare le prededenti informazioni creando un istogramma che visualizzerà le proporzioni di spazio occupato e libero. Iniziamo scrivendo il codice html per impostare la tabella. Poi, osservando l'output di df, notiamo che i dati sono formattati in colonne e su più righe. Ogni colonna è saparata da una serie di spazi. La prima riga ci serve solo per intitolare le celle della tabella (filesystem, mount point, etc). Le altre righe invece dovranno essere processate da php. In pratica dovremo creare un primo array ($a) i cui elementi saranno le righe dell'output di df e poi, per ogni elemento (riga), dovremo creare un secondo array ($df) contenente i dati restituiti dal comando. Per disegnare l'istogramma potremo tracciare due rattangoli adiacenti: uno rosso, la cui lunghezza è il valore in percentuale dello spazio occupato, ed uno blu lungo tanto quanto la percentuale di spazio libero su disco. Ogni filesystem sarà rappresentato dal rispettivo istogramma salvato in un file gif e poi caricato nella tabella html con il tag <img> . Ecco il programma


<!-- esempio 1 -- >
<html>
<head>
<title>df</title>
</head>
<body>
<table border>
  <tr>
    <td>Filesystem</td>
    <td>Mount point</td>
    <td>Grafico</td>
    <td>Legenda</td>
  </tr>
<?php
  exec("df", $a);
  $k = 1;
  while($k < sizeof($a)) { 
    $df = split(" +", $a[$k]);
    // ---
    $img = imagecreate(200, 50);
    $bianco = imagecolorallocate($img, 255, 255, 255);
    $rosso = imagecolorallocate($img, 255, 0, 0);
    $blu = imagecolorallocate($img, 0, 0, 255);
    imagefilledrectangle($img, 0, 0, $df[4]*2, 50, $rosso);
    imagefilledrectangle($img, $df[4]*2, 0, 100*2, 50, $blu);
    // ---
    imagegif($img, "/www/dati/img$k.gif");
    echo "<tr>";
    echo "<td valign=center>$df[0]</td>";
    echo "<td valign=center>$df[5]</td>";
    echo "<td valign=center><img src=dati/img$k.gif></td>";
    echo "<td valign=center>Spazio totale: $df[1] Kb<br><font color=red>Spazio occupato: $df[2]Kb</font><br><font color=blue>Spazio libero: $df[3] Kb</font></td>";
    echo "</tr>";
    $k++;
  }
?>
</table>
</body>
</html>

img_articolo

Una buona idea sarebbe quella di usare un grafico a torta anziché un istogramma. Purtroppo la libreria gd è sprovvista di funzioni per la creazione di settori circolari colorati. Non ci resta altro che aguzzare l'ingegno ed usare la funzione imagearc(). In primo luogo si crea una immagine di 100 per 100 pixel perché dovrà contenere settori circolari di raggio pari a 50 pixel. Poi si calcola l'angolo ($angses) cioè il punto finale ed iniziale degli archi rosso e blu che rispettivamente rappresentano la percentuale di spazio occupato e libero dei filesystem. Disegnamo gli archi. Successivamente dovremo disegnare due segmenti che partono dal centro degli archi (coordinate 50, 50) ed arrivano uno al punto di inizio dell'arco rosso e l'altro al suo punto finale. Mentre le coordinate del primo punto sono note (100, 50) le coordinale del punto finale ($x, $y) verranno calcolate usando un famoso teorema sui triangoli rettangoli (chi ha studiato un po' di trigonometria dovrebbe ricordarlo). Le funzioni seno e coseno di php rihiedono come parametro un angolo espresso in radianti. Trasformiamo l'angolo $angses in $angrad utilizzando una nota formula di conversione

angolo in radianti = angolo sessagesimale * pigreco / 180

Bene, ora possiamo calcolare le coordinate $x e $y e disegnae i segmenti. Finalmente otteniamo dei veri settori circolari. Adesso dobbiamo colorare di rosso e di blu i due settori del cerchio utilizzando la funzione imagefill(). Ci servono le coordinate di due punti interni agli spicchi della circonferenza ($xrosso, $yrosso e $xblu, $yblu). Dopo averle calcolate potremo scrivere le due fuzioni per dipingere i due settori generando un vero grafico a torta. Quanto finora detto è tradotto in linguaggio php3 proprio qui sotto


// esempio 2
$img = imagecreate(100, 100);
$bianco = imagecolorallocate($img, 255, 255, 255);
$rosso = imagecolorallocate($img, 255, 0, 0);
$blu = imagecolorallocate($img, 0, 0, 255);
$angses = 360 * $df[4] / 100;
imagearc($img, 50, 50, 100, 100, 0, $angses, $rosso);
imagearc($img, 50, 50, 100, 100, $angses, 360, $blu);
$angrad = $angses * M_PI / 180;
$x = 50 + 50 * cos($angrad);
$y = 50 + 50 * sin($angrad);
imageline($img, 50, 50, $x, $y, $rosso);
imageline($img, 50, 50, 100, 50, $rosso);
$angses -= 2;
$angrad = $angses * M_PI / 180;
$xrosso = 50 + 48 * cos($angrad);
$yrosso = 50 + 48 * sin($angrad);
imagefill($img, $xrosso, $yrosso, $rosso);
$angses += 4;
$angrad = $angses * M_PI / 180;
$xblu = 50 + 48 * cos($angrad);
$yblu = 50 + 48 * sin($angrad);
imagefill($img, $xblu, $yblu, $blu);

Proviamo a sostituire il blocco di codice racchiuso tra i commenti // --- dell'esempio 1 con lo script appena proposto (esempio 2) e salviamo il tutto nel file df.php3.

img_articolo

fire.gif

Data creazione HTML: Gennaio 2000
Autore: Francesco Munaretto
E-mail: NoSpam@thank.you
exclaim.gif