Creare PNG trasparenti con PHP

Con le ultime versioni dei browser, Internet Explorer incluso, è finalmente possibile sfruttare le potenzialità grafiche offerte dalle immagini PNG (acronimo per Portable Network Graphics).

Questo formato grafico esiste dal lontano 1995; da poco, però, si è imposto definitivamente come soluzione ideale per le aree di trasparenza di una pagina web, soppiantando le immagini GIF. La qualità estetica della trasparenza non è assolutamente paragonabile visto che, a differenza del formato GIF, è possibile definire il livello di opacità delle singole zone dell’immagine (grazie al canale Alpha), ottenendo risultati spesso entusiasmanti.

Oggi vedremo un breve set di istruzioni con il quale andare a generare dinamicamente immagini PNG (più o meno trasparenti) in modo davvero semplice, tramite PHP e le sue librerie GD (librerie che probabilmente troverete già installate sul server o sulla vostra installazione locale di test).

Il nostro obiettivo è creare un’immagine con uno sfondo di un colore unico (trasparente, semitrasparente oppure totalmente opaco). Aggiungeremo poi un testo a scelta, applicandogli un’ombra semitrasparente nera e posizionando il tutto al centro dell’immagine. Il testo, inoltre, sarà scritto con un font a nostro piacimento, di cui ci servirà semplicemente il file .ttf.

Il codice passo per passo

Vediamo le istruzioni necessarie per giungere al nostro obiettivo.

Innanzi tutto definiamo le variabili: il testo da scrivere e le dimensioni che avrà l’immagine.

$testo = "Io sono il testo!";
$larghezza = 500;
$altezza = 200;

Poi definiamo il font (indichiamo esattamente il nome del file .ttf, che nel nostro caso sarà posizionato nella stessa directory del file php), la dimensione del testo e l’angolazione (qui 0, quindi nulla).

$font = 'HITROAD.ttf';
$dimensione_testo = 40;
$angolazione_testo = 0;

Successivamente andiamo a calcolare, grazie alla funzione imagettfbbox lo spazio occupato dal testo. Alla funzione passiamo la dimensione del testo, l’angolazione, il font ed il testo. Abbiamo già definito tutto precedentemente.

$box_testo = imagettfbbox($dimensione_testo, $angolazione_testo, $font, $testo);

Il risultato, la variabile $box_testo, è un array che contiene i seguenti 8 valori:
[0] angolo inferiore sinistro (X) – [1] angolo inferiore sinistro (Y)
[2] angolo inferiore destro (X) – [3] angolo inferiore destro (Y)
[4] angolo superiore destro (X) – [5] angolo superiore destro (Y)
[6] angolo superiore sinistro (X) – [7] angolo superiore sinistro (Y)

Con questi valori possiamo andare a definire la posizione che dovrà avere il riquadro di testo all’interno dell’immagine:

$x_off_testo = ($larghezza/2) - ($box_testo[4] / 2);
$y_off_testo = ($altezza/2) - ($box_testo[5] / 2);

Ciò che abbiamo visto finora ci basterà per posizionare correttamente il testo. Ora passiamo alla vera e propria creazione dell’immagine. La prima riga da scrivere definisce un’immagine (la variabile $immagine) di larghezza e altezza specificate:

$immagine = imagecreatetruecolor($larghezza, $altezza);

Passiamo alla definizione dei colori (con canale Alpha) che verranno utilizzati nell’immagine. Impostiamo il valore RGB indicandolo in formato esadecimale. Per questo esempio ci servono 3 colori: per lo sfondo, il testo e l’ombra del testo.

Impostiamo lo sfondo rosso (per ora totalmente opaco, successivamente varieremo la trasparenza); il testo bianco e l’ombra del testo nero con semi-trasparenza (valore 80 su 127).

$sfondo = imagecolorallocatealpha($immagine, 0xFF, 0, 0, 0);
$bianco = imagecolorallocatealpha($immagine, 0xFF, 0xFF, 0xFF, 0);
$nero = imagecolorallocatealpha($immagine, 0, 0, 0, 80);

Ora “riempiamo” l’immagine creata con il colore di sfondo, ed inoltre dichiariamo che la trasparenza del canale Alpha deve essere salvata nel risultato finale.

imagefill($immagine, 0, 0, $sfondo);
imagesavealpha($immagine, TRUE);

Per ora otteniamo semplicemente un rettangolo rosso (di 500 x 200 pixel):

creare-png-trasfepenti-php-1

Fatto ciò dobbiamo inseriamo il testo, partendo dalla sua ombra, visto che questa dovrà stare sotto al testo vero e proprio. Perciò utilizziamo la funzione imagettftext in questo modo:

imagettftext($immagine, $dimensione_testo, $angolazione_testo, $x_off_testo, $y_off_testo+3, $nero, $font, $testo);

Se ci fermassimo qui avremmo questo risultato:

creare-png-trasfepenti-php-2

Infine ripetiamo quanto visto sopra variando solamente il colore e togliendo il piccolo scostamento di 3 pixel (che ci consente di vedere l’ombra):

imagettftext($immagine, $dimensione_testo, $angolazione_testo, $x_off_testo, $y_off_testo, $bianco, $font, $testo);

Non resta che visualizzare il risultato a video, in questo modo:

header('Content-type: image/png');
imagepng($immagine);
imagedestroy($immagine);

creare-png-trasfepenti-php-3

Se vogliamo invece salvare l’immagine PNG nella directory del file php, al posto delle 3 righe viste sopra dobbiamo mettere questa:

imagepng($immagine, 'risultato.png');

Una piccola variazione

Abbiamo visto come ottenere un’immagine con sfondo rosso. Se volessimo invece avere uno sfondo totalmente trasparente oppure semi-trasparente dovremmo variare solamente la riga dove abbiamo definito il colore di sfondo. Ecco come fare:

Riga originale (rosso – totalmente opaco – valore trasparenza 0 su 127):

$sfondo = imagecolorallocatealpha($immagine, 0xFF, 0, 0, 0);

creare-png-trasfepenti-php-4

Semitrasparenza (rosso – semi-trasparente – valore trasparenza 80 su 127):

$sfondo = imagecolorallocatealpha($immagine, 0xFF, 0, 0, 80);

creare-png-trasfepenti-php-5

Trasparenza (rosso – totalmente trasparente – valore trasparenza 127 su 127):

$sfondo = imagecolorallocatealpha($immagine, 0xFF, 0, 0, 127);

creare-png-trasfepenti-php-6

Il codice completo

Infine ecco tutto il codice visto sopra:

<?php
$testo = "Io sono il testo!";
$larghezza = 500;
$altezza = 200;
$font = 'HITROAD.ttf';
$dimensione_testo = 40;
$angolazione_testo = 0;
$box_testo = imagettfbbox($dimensione_testo, $angolazione_testo, $font, $testo);
$x_off_testo = ($larghezza/2) - ($box_testo[4] / 2);
$y_off_testo = ($altezza/2) - ($box_testo[5] / 2);
$immagine = imagecreatetruecolor($larghezza, $altezza);
$sfondo = imagecolorallocatealpha($immagine, 0xFF, 0, 0, 0);
$bianco = imagecolorallocatealpha($immagine, 0xFF, 0xFF, 0xFF, 0);
$nero = imagecolorallocatealpha($immagine, 0, 0, 0, 80);
imagefill($immagine, 0, 0, $sfondo);
imagesavealpha($immagine, TRUE);
imagettftext($immagine, $dimensione_testo, $angolazione_testo, $x_off_testo, $y_off_testo+3, $nero, $font, $testo);
imagettftext($immagine, $dimensione_testo, $angolazione_testo, $x_off_testo, $y_off_testo, $bianco, $font, $testo);
// alternativa 1: visualizzazione a video
header('Content-type: image/png'’);
imagepng($immagine);
imagedestroy($immagine);
// alternativa 2: salvataggio immagine
// imagepng($immagine, 'risultato.png');
?>

Ecco i link dove potete trovare i dettagli di tutte le funzioni utilizzate:
http://php.net/manual/en/function.imagettfbbox.php
http://php.net/manual/en/function.imagecreatetruecolor.php
http://php.net/manual/en/function.imagecolorallocatealpha.php
http://php.net/manual/en/function.imagefill.php
http://php.net/manual/en/function.imagesavealpha.php
http://php.net/manual/en/function.imagettftext.php
http://php.net/manual/en/function.imagepng.php
http://php.net/manual/en/function.imagedestroy.php

 

di Massimo Cinquini, Web Developer @ Voxart
Seguimi su Twitter oppure aggiungimi su Google Plus

 

Restiamo in contatto con la nostra newsletter

Unisciti al gruppo e non perderti nemmeno un aggiornamento dal mondo Voxy! Ogni mese un nuovo argomento utile alla tua attività e alla tua sete di conoscenza.

Iscriviti



    Unisciti al gruppo e non perderti nemmeno un aggiornamento dal mondo Voxy! Ogni mese un nuovo argomento utile alla tua attività e alla tua sete di conoscenza.

    Inserisci il tuo indirizzo email:
    Autorizzo Privacy Ho letto l'Informativa Privacy ed acconsento all'invio ed al trattamento dei miei dati personali. *
    Autorizzo Invio Newsletter Acconsento al trattamento dei dati per invio di comunicazioni promozionali da Voxart. *
    No grazie, non voglio ricevere la newsletter.