http://forum.html.it/forum/showthread.php?threadid=694523

upload+resize+thumbnails 
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: 
code:--------------------------------------------------------------------------------
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. 
code:--------------------------------------------------------------------------------
<form action="upload.php" method="post" enctype="multipart/form-data">
File:<br/>
<input name="file" type="file"><br/>
Nome:<br/>
<input name="new_name" type="text"><br/>
<br/>
<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 

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: 

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: 

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: 

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 

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ì: 

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. 

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: 

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 

PHP:--------------------------------------------------------------------------------
$img->Free();
--------------------------------------------------------------------------------

e subito dopo il metodo DeleteFile() della classe FileUpload, per liberare la memoria: 

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 

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 

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<br/>';
//In ogni caso cancello il file uploadato nella cartella ./tmp
$up->DeleteFile();
echo '<a href="view.php">Guarde le immagini</a>';
}
?>
--------------------------------------------------------------------------------

Il file view.php, semplicemente visualizza le thumbnails e le linka alle immagini grosse 
view.php 

PHP:--------------------------------------------------------------------------------

<?PHP
include_once 'config.php';
$dir = dir(THUMB_DIR);
while($img = $dir->read()){
if( ($img != '.') & ($img != '..') )
echo '<a href="'.IMAGE_DIR.'/'.$img.'"><img src="'.THUMB_DIR.'/'.$img.'"></a>';
}
?>
--------------------------------------------------------------------------------






per creare una thumb e mantenere le proporzioni: 

code:--------------------------------------------------------------------------------
<form action="test.php" method="post">
larghezza<br>
<input type="text" name="larghezza"><br>
altezza<br>
<input type="text" name="altezza"><br>
<input type="submit" value="invia">
</form>
<?
if (isset($_POST['larghezza']))
$larghezza=$_POST['larghezza'];
else
$larghezza=0; 

if (isset($_POST['altezza']))
$altezza=$_POST['altezza'];
else
$altezza=0; 

if (($larghezza>400) || ($altezza>400))
if ($larghezza>$altezza)
{
$altezza = $altezza * 400/$larghezza;
$larghezza = 400;
}
else
{
$larghezza = $larghezza * 400/$altezza;
$altezza = 400;
}

echo "altezza ".$altezza."<br>";
echo "larghezza ".$larghezza."<br>"; 

?>
--------------------------------------------------------------------------------




Se il file esiste già, e non lo si rinomina,viene sovrascritto! 
Basta mettere un controllo prima di copiare l'immagine usando: 

PHP:--------------------------------------------------------------------------------
file_exists (filename);
--------------------------------------------------------------------------------

Se esiste già,la rinomini.... 






Per abilitare l'estensione apri il tuo php.ini: 

cerca la stringa "extension=php_gd2.dll" 
e decommentala togliendo il ";" iniziale... 






Un'ultima cosa: e se l'immagine grande non voglio ridimensionarla, mantenedo le dimensioni originali?

Le immagini grandi vengono salvate nella cartella "img_big", quindi se vuoi visualizzare un immagine senza usare alcuna funzione di resize,basta che la linki normalmente: <img src = "img_big/filename" /> 



Scusate, ho testato script originale come da pillola di xPilux e funzia alla grande però mi dà un problemuccio, il filez che vado ad uploadare senza dargli il nome dal form conserva il nome originale ma raddoppia l'estensione: 

prova.jpg -> prova.jpg.jpg 

ho rovistato un pò le classi ma non riesco a trovarne la causa

cmq ho trovato il "bugghino": 

nel file image.class.php la riga 
imagejpeg($dest_image, $filename.'.jpg', $quality); 
va sostituita con 
imagejpeg($dest_image, $filename, $quality); 

e funziona tutto alla grande 


Ho provato ad uploadare un img 2272 x 1712 da 1MB e funziona benissimo sia con php4 che col 5... 

credo che si sia dovuto alla configurazione del memory_limit , nel php.ini..