Visto che l'argomento trattato è stato il soggetto di molti degli ultimi post, e dato che è stato chiesto, ho deciso di scrivere questa pillola, sperando di scriverla bene e sperando che possa essere utile e chiara. Il fine di questa pillola è quello di sfruttare le potenzialità di PHP per fare l'upload di un immagine e creare un immagine ridimensionata per esempio a 400 pixel di altezza e allo stesso tempo creare una thumbnail da 75 pixel di altezza della stessa immagine.
Per fare ciò organizziamo il filesystem in questo modo:
codice:
img_big //cartella in cui metteremo le immagini
img_small //cartella in cui metteremo le thumbnail
include //cartella in cui metteremo la classi php
|_image.class.php
|_upload.class.php
tmp //cartella temporanea in cui metteremo i file uploadati
config.php
index.php
upload.php
view.php
Cosa dobbiamo fare:
[1] Creare un form con 2 campi: uno sarà un campo di tipo file per scegliere l'immagine dal proprio hd e l'altro sarà semplicemente di tipo 'text',per scegliere il nome che l'immagine avrà sul server; se il campo non è compilato il file avrà il nome originale che avevo sul nostro hc.
codice:
<form action="upload.php" method="post" enctype="multipart/form-data">
File:
<input name="file" type="file">
Nome:
<input name="new_name" type="text">
<input name="submit_upload" type="submit" value="Invia">
</form>
Non dimenticate enctype="multipart/form-data" altrimenti non funziona.
[2] Tramite POST manderemo i dati del form alla pagina upload.php: qui richiameremo il file './include/upload.class.php' per fare l'upload dell'immagine, e tramite il file './include/image.class.php'verranno create le immagini e le thumbnails.
Vediamo il codice delle 2 classi e poi commenterò il file upload.php che sfrutta appunto queste 2 classi:
upload.class.php
Codice PHP:
<?
class FileUpload{
var $up_dir; //la directory temporanea in cui verrà uploadata l'img
var $filename; //il nome del file
var $new_filename; //il nuovo nome del file se vogliamo rinominarlo
function FileUpload($up_dir){
$this->up_dir = $up_dir;
}
function RenameFile($new_filename){
$this->new_filename = $new_filename;
}
function Upload($files){
if(!file_exists($this->up_dir))
die('La directory non esiste!');
$this->filename = ($this->new_filename) ? $this->new_filename :$files['name'];
if(trim($files["name"]) == "")
die("Non hai indicato il file da uploadare!");
if(is_uploaded_file($files["tmp_name"])){
move_uploaded_file($files["tmp_name"],$this->up_dir."/".$this->filename)
or die("Impossibile spostare il file;controlla l'esistenza o i permessi della directory!");
}else
die ("Problemi nell'upload del file ".$files["name"]);
}
function DeleteFile(){
unlink($this->up_dir . '/' . $this->filename);
}
}
?>
Il costruttore della classe riceve solo un parametro: il nome della directory in cui uploadare il file.
Quindi procederemo cosi:
Codice PHP:
$up = new FileUpload('./tmp');
Prima di effettuare l'upload abbiamo la possibilità di rinominare il file con il metodo RenameFile();; Quindi potremo rinominare il file sul server in questo modo:
Codice PHP:
$up->RenameFile($_POST['new_name']); //che è la variabile che arriva dal nostro form
A questo punto chiamando il metodo Upload, ci sarà l'effettivo upload del file:
Codice PHP:
$up->Upload($_FILES['file']); //gli mandiamo il file che arriva dal nostro form
Una volta uploadato il file possiamo creare le immagini e le thumbnails sfruttando la classe Image.
image.class.php
Codice PHP:
<?PHP
class Image{
var $src_filename;
var $src_witdh;
var $src_height;
var $src_type;
var $src_attr;
var $src_image;
function Image($filename){
$this->src_filename = $filename;
$this->GetImageInfo();
}
function GetImageInfo(){
list($this->src_width,$this->src_height, $this->src_type, $this->src_attr) = getimagesize($this->src_filename);
}
function CreateSourceImage(){
switch($this->src_type){
case 1:
$this->src_image =imagecreatefromgif($this->src_filename);
break;
case 2:
$this->src_image =imagecreatefromjpeg($this->src_filename);
break;
case 3:
$this->src_image =imagecreatefrompng($this->src_filename);
break;
default: return false;
}
return true;
}
function SaveProportionateImage($filename, $quality, $height){
$dest_height = $height;
$ratio = $this->src_height / $dest_height;
$dest_image = imagecreatetruecolor( $this->src_width / $ratio,$dest_height);
imagecopyresampled($dest_image, $this->src_image, 0, 0, 0, 0,
$this->src_width / $ratio,
$this->src_height / $ratio,
$this->src_width,
$this->src_height);
imagejpeg($dest_image, $filename.'.jpg', $quality);
imagedestroy($dest_image);
}
function Free(){
imagedestroy($this->src_image);
}
}
?>
Il costruttore di questa classe accetta un parametro che è la path dell'immagine che andremo a ridimensionare. Quindi istanzieremo la classe così:
Codice PHP:
$img = new Image('./tmp/' . $up->filename);
//$up->filename è il nome del file uploadato o il 'nuovo_nome' del file
//in caso abbiamo usato il metodo RenameFile della classe FileUpload.
A questo punto, sfruttando la libreria GD di PHP, andremo a lavorare sulle immagini. Come prima cosa dovremo creare l'immagine sorgente leggendo il file dell'immagine uploadata: non sapendo a priori il tipo di immagine, faremo uno switch su type, restituito dalla funzione getimagesize(), che ritorno il tipo di immagine oltre alla sua dimensione.
Per fare ciò useremo il metodo CreateSourceImage() della nostra classe Image.
Codice PHP:
$result = $img->CreateSourceImage();
Questo metodo ritorna un booleano: true se è tutto andato a buon fine, false se il tipo di immagine non è supportato,o se addirittura il file uploadato non è un immagine.
Se il risultato è false, non possiamo andare avanti, al contrario procediamo creando il l'immagine e poi la thumbnail. Semplicemente richiameremo lo stesso metodo due volte,mandando come parametro $height due altezze diverse.
Il metodo in questione è SaveProportionateImage() che accetta 3 parametri:
[*] $filename, che sarà il file in cui verrà salvata l'immagine ridimensionata.
[*] $quality, che sarà un intero compreso tra 0 e 100, che il nostro metodo passerà alla funzione delle GD per creare l'immagine. 0 è la qualità minima, 100 la massima.
[*] $height sarà l'altezza della massima della nostra immagine.
In realtà il metodo può essere implementato facendo in modo che, se l'altezza dell'immagine originale sia inferiore a $height, questa non sia ridimensionata, altrimenti verrebbe ingrandita e quindi perderebbe qualità.
Passeremo solo il parametro $height e non $width, in modo da controllare l'altezza dell'immagine che creeremo, senza però storpiarla o tagliarla;
Ad ogni modo sarebbe facile implementare un secondo metodo che crei l'immagine prendendo altezza e larghezza come parametri.
Quindi faremo:
Codice PHP:
$img->SaveProportionateImage('./img_big' . $up->filename, 100, 400);
$img->SaveProportionateImage('./img_small' . $up->filename, 100, 75);
L'immagine verrà perciò salvata due volte con lo stesso nome ma in cartelle diverse e con dimensione diversa.
A questo punto chiameremo il metodo Free() della classe Image per liberare la memoria
Codice PHP:
$img->Free();
e subito dopo il metodo DeleteFile() della classe FileUpload, per liberare la memoria:
Codice PHP:
$up->DeleteFile();
Ora posto gli altri due file, che in realtà fanno quello che ho appena riassunto: in config.php, definisco semplicemento tutte le costanti che useremo nel nostro script:
config.php
Codice PHP:
<?PHP
define('TMP_DIR', './tmp');
define('IMAGE_DIR', './img_big');
define('THUMB_DIR', './img_small');
define('IMAGE_QUALITY', 80);
define('THUMB_QUALITY', 70);
define('IMAGE_HEIGHT', 400);
define('THUMB_HEIGHT', 75);
?>
upload.php, è il file che riceve i dati dal form,quindi non fa altro che sfruttare le classi e i metodi descritti sopra:
upload.php
Codice PHP:
<?PHP
if(!isset($_POST['submit_upload'])){
header("Location: index.php");
}else{
include_once 'config.php';
//faccio l'upload dell'img
include_once './include/upload.class.php';
if(!isset($_FILES)) $_FILES = $HTTP_POST_FILES;
if(!isset($_SERVER)) $_FILES = $HTTP_POST_VARS;
$up = new FileUpload(TMP_DIR);
$up->RenameFile($_POST['new_name']);
$up->Upload($_FILES['file']);
//adesso ridimensiono l'img a 400 x 400
include_once './include/image.class.php';
$img = new Image(TMP_DIR . '/' . $up->filename);
//creo l'immagine sorgente
$result = $img->CreateSourceImage();
//se il tipo di immagine è supportato
//salvo 2 file:
//uno con l'img grande e uno con l'img piccola
//nelle rispettive directory
if($result){
//salvo l'immagine con altezza 400 lasciandola proporzionata
$img->SaveProportionateImage(IMAGE_DIR . '/' . $up->filename, IMAGE_QUALITY, IMAGE_HEIGHT);
//salvo l'immagine con altezza 75 lasciandola proporzionata
$img->SaveProportionateImage(THUMB_DIR . '/' . $up->filename, THUMB_QUALITY, THUMB_HEIGHT);
//libero la memoria cancellando l'immagine sorgente
$img->Free();
}
//se il tipo di img non è supportata
//o se il file uploadato nn è un immagine
else
echo 'Immagine non valida
';
//In ogni caso cancello il file uploadato nella cartella ./tmp
$up->DeleteFile();
echo '[url="view.php"]Guarde le immagini[/url]';
}
?>
Il file view.php, semplicemente visualizza le thumbnails e le linka alle immagini grosse
view.php
Codice PHP:
<?PHP
include_once 'config.php';
$dir = dir(THUMB_DIR);
while($img = $dir->read()){
if( ($img != '.') & ($img != '..') )
echo '[url="'.IMAGE_DIR.'/'.$img.'"][img]'.THUMB_DIR.'/'.$img.'[/img][/url]';
}
?>
Spero di non aver scritto qualche cavolata...in tal caso ditemelo!
Spero anche che possa servire quello che ho scritto...fatemi sapere 
-Pilu-