Eccoci al secondo appuntamento dedicato a l’arte di elaborare l’immagine con php, parleremo oggi del ridimensionamento delle immagini e del taglio, inoltre ci divertiremo con i filtri.
Scala e taglia
Il metodo generalmente più opportuno per ridimenzionare un immagine è quello di scalarla e poi tagliarla, questo perchè permette di ridimenzionarla perdendo solo una minima parte dell’immagine.
Per prima cosa creeremo la nostra immagine della dimensione desiderata (questa volta useremo imagecreatetruecolor() avendo bisogno della gamma di colori più completa):
$riquadro=imagecreatetruecolor(320,400);
Ora dobbiamo creare un oggetto immagine partendo da un file png che posizioneremo nella directory img/
$immagine=imagecreatefrompng('img/immagine.png');
ps. oltre imagecreatefrompng() abbiamo a nostra disposizione anche imagecreatefromgif() e imagecreatefromjpeg(). Ovviamente useremo quella dedicata al nostro file.
Andremo quindi ad incollare la nostra immagine nel riquadro usando la funzione imagecopymerge() la quale richiede 9 parametri:
- immagine di destinazione
- immagine da incollare
- coordinata x di partenza dell’immagine di destinazione
- coordinata y di partenza dell’immagine di destinazione
- coordinata x di partenza dell’immagine da incollare
- coordinata y di partenza dell’immagine da incollare
- larghezza dell’immagine da incollare
- altezza dell’immagine da incollare
- opacità dell’immagine da incollare
una funzione simile è imagecopy() che non gestisce l’opacità, quindi non richiede il nono parametro.
// incolliamo l'immagine nel riquadro imagecopymerge($riquadro, $immagine, 0, 0, 0, 0, 1200, 1125, 100);
Ma il risultato che otteniamo non è quello desiderato, lo possiamo esemplificare come segue:
L’immagine (rappresentata dal riquadro azzurro) eccede il riquadro (rappresentato dalla linea rossa) in entrambe le dimensioni. Ecco quindi che dovremo andare a fare una serie di calcoli per scalare e centrare la nostra immagine. Il primo passo consiste nell’ottenere le dimensioni dell’immagine usando le funzioni imagesx() ed imagesy()
// dim dell’immagine $i_width=imagesx($img); // larghezza dell’immagine $i_height=imagesy($img); // altezza dell’immagine
Ora però dobbiamo ragionare sulla logica della nostra operazione: se in questo caso adattassimo la larghezza l’immagine in altezza sarebbe più piccola del nostro riquadro, ma non è detto neanche che non possa succedere il contrario, quindi come facciamo a decidere quale grandezza adattare? con un semplice calcolo matematico:
// dim del riquadro $r_width=320; $r_height=400; // calcolo le proporzioni $pr_width=$i_width/$r_width; $pr_height=$i_height/$r_height;
Ora abbiamo calcolato le proporzioni delle larghezze e delle altezze, la proporzione minore è quella che comanderà la scala:
// confronto le proporzioni if($pr_width<$pr_height){ // modifichiamo la larghezza $new_width=$r_width; // calcolo la nuova altezza $new_height=$i_height/$pr_width; }else{ // modifichiamo l'altezza $new_height=$r_height; // calcolo la nuova larghezza $new_width=$i_width/$pr_height; }
Se a questo punto scaliamo l’immagine usando la funzione imagescale() e poi incolliamo l’immagine scalata come segue:
// ridimenzioniamo l’immagine $immagine_scalata=imagescale($immagine, $new_width, $new_height); // incolliamo l'immagine nel riquadro imagecopymerge($riquadro, $immagine_scalata, 0, 0, 0, 0, $new_width, $new_width, 100);
otterremo un risultato del genere:
Come potete vedere l’immagine (rappresentata dal riquadro azzurro) è stata adattata al riquadro (rappresentato dalla linea rossa) ma viene incollato in una posizione decentrata, per centrarlo dovremmo andare a modificare i parametri 3 e 4 che passiamo alla funzione imagecopymerge().
// calcolo le coordinate $r_x=($r_width/2)-($new_width/2); $r_y=($r_height/2)-($new_height/2); // incolliamo l'immagine nel riquadro imagecopymerge($riquadro, $immagine_scalata, $r_x, $r_y, 0, 0, $new_width, $new_width, 100);
ecco che finalmente abbiamo la nostra immagine scalata, centrata e tagliata, le zone eccedenti i lati del riquadro verranno infatti escluse dal risultato finale.
Divertiamoci con qualche “effetto speciale”
Eccoci arrivati al momento del divertimento puro, applicheremo tutti i filtri a nostra disposizione, l’elenco completo lo si può trovare qui: http://www.php.net/manual/en/function.imagefilter.php.
I filtri sono:
- IMG_FILTER_NEGATE
- IMG_FILTER_GRAYSCALE
- IMG_FILTER_BRIGHTNESS
- IMG_FILTER_CONTRAST
- IMG_FILTER_COLORIZE
- IMG_FILTER_EDGEDETECT
- IMG_FILTER_EMBOSS
- IMG_FILTER_GAUSSIAN_BLUR
- IMG_FILTER_SELECTIVE_BLUR
- IMG_FILTER_MEAN_REMOVAL
- IMG_FILTER_SMOOTH
- IMG_FILTER_PIXELATE
Vediamo come usarli. La chiave è la funzione imagefilter() la quale richiede minimo 2 parametri:
- immagine a cui applicare il filtro
- nome del filtro
Alcuni filtri però necessitano di altri parametri, li vedremo man mano che li analizzeremo.
Questa è l’immagine che useremo per illustrare gli effetti dei vari filtri:
Andiamo ora ad analizzare tutti i filtri singolarmente.
Negate: negativo dell’immagine passata come parametro
non richiede altri parametri
imagefilter($riquadro, IMG_FILTER_NEGATE);
Grayscale: toglie la saturazione
non richiede altri parametri
imagefilter($riquadro, IMG_FILTER_GRAYSCALE);
Brightness: modifica la luminosità dell’immagine
richiede come parametero l’intensità (positiva aumenta la luminosità negativa diminuisce)
imagefilter($riquadro, IMG_FILTER_BRIGHTNESS, 50);
Contrast: modifica il contrasto dell’immagine
richiede come parametro l’intensità (positiva diminuisce il contrasto negativa aumenta)
imagefilter($imm, IMG_FILTER_CONTRAST, -50);
Colorize: applica un filtro di colore all’immagine
richiede tre parametri aggiuntivi che indicano rispettivamente i livelli dei colori RGB (rosso, verde e blu)
imagefilter($riquadro, IMG_FILTER_COLORIZE, 255, 0, 0);
Edgedetect: trova e evidenzia i bordi
non richiede altri parametri
imagefilter($imm, IMG_FILTER_EDGEDETECT);
Emboss: crea una sorta di effetto “bassorilievo”
non richiede altri parametri
imagefilter($riquadro, IMG_FILTER_EMBOSS);
Gaussian Blur: applica una sfocatura gaussiana all’immagine
non richiede altri parametri
imagefilter($riquadro, IMG_FILTER_GAUSSIAN_BLUR);
Selective Blur: applica una sfocatura ma selettiva (ossia sfoca le varie superfici che identifica nell’immagine)
non richiede altri parametri
imagefilter($imm, IMG_FILTER_SELECTIVE_BLUR);
Removal: senza entrare in deddagli di difficile comprenzione, dà l’effetto di uno schizzo
non richiede altri parametri
imagefilter($riquadro, IMG_FILTER_MEAN_REMOVAL);
Smooth: ammorbidisce l’immagine
richiede come parametro l’intensità dell’effetto
imagefilter($imm, IMG_FILTER_SMOOTH, 7);
Pixelate: sfoca l’immagine con effetto pixel
richiede come parametro la dimensione dei singoli pixel e la selezione della modalità di effetto (true=graduale, false=netta)
imagefilter($imm, IMG_FILTER_PIXELATE, 8, true);
Creare filtri personalizzati
I filtri a tua disposizione ti stanno stretti? nessun problema, puoi unirli per crearne di nuovi. Diciamo ad esempio che abbiamo la necessità di sfumare la foto in base ad un valore scelto. Abbiamo visto però che usando IMG_FILTER_GAUSSIAN_BLUR non abbiamo la possibilità di inserire un parametro. Andiamo perciò a creare la funzione che deciderà come si comporta il nostro filtro MY_BLUR()
function MY_BLUR($img, $ammount=NULL){ if(is_numeric($ammount) && $ammount > 1){ for($i = 1; $i <= $ammount; $i++){ imagefilter($img, IMG_FILTER_GAUSSIAN_BLUR); } }else{ imagefilter($img, IMG_FILTER_GAUSSIAN_BLUR); } }
in sostanza non facciamo altro che impostare un ciclo che ripete l’effetto per l’ammontare di volte che decidiamo tramite il parametro $ammount. Quindi ora facendo:
MY_BLUR($riquadro, 50);
otterremo:
E se volessimo creare un effetto più complesso? ad esempio una foto un po retrò? beh che dire divertitevi a sperimentare, vi posto la mia versione, fatemi vedere le vostre:
Il codice che ho utilizzato per questo effetto lo trovate qui: https://dl.dropboxusercontent.com/u/25346856/webhouse/retro.zip
ps. un ringrazziamento speciale alla mia coniglietta Meggy che ha fatto da modella ;P