Script PHP – Uploader une image et la redimensionner
J’ai eu besoin pour mon prochain Portfolio d’un script pour uploader une image en PHP et la redimensionner pour un meilleur affichage.
Je fais donc un petit tutoriel expliquant la réalisation et le fonctionnement du script.
Formulaire:
On commence par écrire le formulaire en HTML qui permet de donner le chemin du fichier à uploader et envoyer le fichier à PHP ensuite. Créer un fichier upload.php et copiez le code ci-dessous.
Pour créer un formulaire, nous utilisons la balise form ainsi que l’attribut enctype avec la valeur multipart/form-data pour indiquer que le formulaire est constitué de plusieurs parties (données du fichier).
Le champ de type file permettra à l’utilisateur de spécifier le chemin du fichier à uploader avec un bouton Parcourir.
Nous ajoutons ensuite un bouton de soumission.
Vous pouvez également ajouter un champ de type hidden avec pour nom MAX_FILE_SIZE et valeur la taille maximale en octet, que le fichier peut faire.
Exemple: <input name= »MAX_FILE_SIZE » size= »1048576″ type= »hidden » > pour des fichiers de 1Mo.
Upload en PHP:
Si le formulaire a été utilisé, la variable $_POST[‘upload’] existe (voir les variables de formulaire ici pour plus d’explications). On teste donc avec la fonction isset l’existence de la variable. Si tout est bon on peut continuer.
La variable $content_dir est le dossier où votre image sera stockée. S’il n’existe pas, il faudra le créer.
Il faut faire ensuite quelques tests de sécurité: d’abord sur l’extension du fichier, puis un test de sécurité pour voir l’adresse du fichier ne contient pas un autre fichier par exemple (hack.php.jpeg).
La fonction move_uploaded_file déplace ensuite le fichier uploadé (qui est pour l’instant dans un dossier temporaire) dans le dossier voulu.
On va maintenant s’occuper du redimensionnement de l’image.
Redimensionnement de l’image:
Nous allons utiliser les fonctions imagecopyresampled, et getimagesize. Puis nous utiliserons les fonctions imagecreatefromjpeg et imagejpeg (et leur équivalent pour gif et png).
La variable $taille_min est très importante; elle définit la taille du plus petit côté de l’image finale.
On stocke dans un tableau $donnees la tailles de l’image uploadée ($donnees[0]=largeur et $donnees[1]=hauteur).
On créé une nouvelle image avec imagecreatefromjpeg (utiliser imagecreatefromgif pour les images gif par exemple).
On teste ensuite si notre image est en paysage ou en portrait grâce aux tailles de $donnees.
On créé deux nouvelles variables contenant les hauteur et largeur finales.
La fonction imagecreatetruecolor créé une nouvelle image de la taille finale voulue.
Puis on redimensionne l’image dans $image_mini grâce à la fonction imagecopyresampled (de meilleure qualité que imagecopyresized). Les paramètres sont les suivants:
– image de destination –> $image_mini
– image source –>$image
– les quatre paramètres suivants servent à décaler la photo mais nous n’en avons pas besoin
– largeur destination
– hauteur destination
– largeur source
– hauteur source
La fonction imagejpeg envoie ensuite l’image redimensionnée dans le dossier correspondant.
Il suffit ensuite de mettre tout le code bout à bout.
$donnees[1]) { //paysage $largeur_finale=round(($taille_min/$donnees[1])*$donnees[0]); $hauteur_finale=$taille_min; } else {//portrait $hauteur_finale=round(($taille_min/$donnees[0])*$donnees[1]); $largeur_finale=$taille_min; } $image_mini = imagecreatetruecolor($largeur_finale, $hauteur_finale); //création image finale imagecopyresampled($image_mini, $image, 0, 0, 0, 0, $largeur_finale, $hauteur_finale, $donnees[0], $donnees[1]);//copie avec redimensionnement imagejpeg ($image_mini, $content_dir.$name_file); echo 'ok'; } ?>Il est possible d’améliorer ce script qui reste basique pour être le plus compréhensible. Voici quelques idées:
– afficher l’image redimensionnée à la fin du script
– gérer différents types d’image avec $donnees[2] qui contient le type de l’image
– stocker la photo originale dans un dossier images et les miniatures dans un autre dossier mini par exemple
– ne pas redimensionner les images qui sont plus petites que la taille minimale avec un test
Si vous avez des questions sur le fonctionnement du script, n’hésitez pas à laisser un commentaire!
Tiens, c’est pas mal ce script … mais il y a quelques petites erreurs …
Je vais peut être le prendre comme base pour un projet, si je le fait évoluer (je vais surement ajouter un backoffice ) je te ferais un post 🙂
Amicalement.
Effectivement, en baptisant le fichier « test.php », définissant le $content_dir = ‘.’; et en remplaçant les deux points-virgules de concaténation des conditions dans les if ça fonctionne pour moi.
Corrigé, merci
Bonsoir et merci pour ce script, cependant j’ai un peu modifier le script et je me trouve face à deux problème, si vous avez une solution serai très gentil de votre part
1. Comment peut améliorer le code pou utiliser le meme formulaire pour uploader plusieurs images sans devoir creer up01-10.php ?
2. Certaine images uploader sont limités par le getimagesize(tmp_file);
ex : 2592px x 1728px (ok)
ex : 5184px x 3456px (ne peux pas etre uploader)
: ci-dessous le code modifier et en passant merci encore à l’auteur.
Le premier fichier qui contient le formulaire (upload.php)
Le deuxième fichier qui traite le upload (up01.php) :
1000000000)
{
exit(« Le fichier n’est pas une image »);
}
// on copie le fichier1 dans le dossier de destination
$name_file1 = $_FILES[‘fichier1’][‘name’];
if( preg_match(‘#[x00-x1Fx7F-x9F/\\]#’, $name_file1) )
{
exit(« Nom de fichier non valide »);
}
////////////////////////////////////////////////
$taille_min_big = 720;
$taille_min_small = 280;
$taille_min_thumb = 44;
$taille_min_vignette = 120;
$donnees = getimagesize($tmp_file);
if(strstr($type_file, ‘jpg’) || strstr($type_file, ‘JPG’) || strstr($type_file, ‘jpeg’)) {
$image = imagecreatefromjpeg($tmp_file);
}
if(strstr($type_file, ‘png’) || strstr($type_file, ‘PNG’)) {
$image = imagecreatefrompng($tmp_file);
}
if(strstr($type_file, ‘gif’) || strstr($type_file, ‘GIF’)) {
$image = imagecreatefromgif($tmp_file);
}
if ($donnees[0] > $donnees[1]) { //paysage
$largeur_finale_big = round(($taille_min_big/$donnees[1])*$donnees[0]);
$hauteur_finale_big = $taille_min_big;
$largeur_finale_small = round(($taille_min_small/$donnees[1])*$donnees[0]);
$hauteur_finale_small = $taille_min_small;
$largeur_finale_thumb = round(($taille_min_thumb/$donnees[1])*$donnees[0]);
$hauteur_finale_thumb = $taille_min_thumb;
$largeur_finale_vignette = round(($taille_min_vignette/$donnees[1])*$donnees[0]);
$hauteur_finale_vignette= $taille_min_vignette;
}
else
{//portrait
$hauteur_finale_big = round(($taille_min_big/$donnees[0])*$donnees[1]);
$largeur_finale_big = $taille_min_big;
$hauteur_finale_small = round(($taille_min_small/$donnees[0])*$donnees[1]);
$largeur_finale_small = $taille_min_small;
$hauteur_finale_thumb = round(($taille_min_thumb/$donnees[0])*$donnees[1]);
$largeur_finale_thumb = $taille_min_thumb;
$hauteur_finale_vignette = round(($taille_min_vignette/$donnees[0])*$donnees[1]);
$largeur_finale_vignette = $taille_min_vignette;
}
$image_big = imagecreatetruecolor($largeur_finale_big, $hauteur_finale_big); //création image finale
imagecopyresampled($image_big, $image, 0, 0, 0, 0, $largeur_finale_big, $hauteur_finale_big, $donnees[0], $donnees[1]);//copie avec redimensionnement
imagejpeg ($image_big, $content_dir_big.$name_file1);
$image_small = imagecreatetruecolor($largeur_finale_small, $hauteur_finale_small); //création image finale
imagecopyresampled($image_small, $image, 0, 0, 0, 0, $largeur_finale_small, $hauteur_finale_small, $donnees[0], $donnees[1]);//copie avec redimensionnement
imagejpeg ($image_small, $content_dir_small.$name_file1);
$image_thumb = imagecreatetruecolor($largeur_finale_thumb, $hauteur_finale_thumb); //création image finale
imagecopyresampled($image_thumb, $image, 0, 0, 0, 0, $largeur_finale_thumb, $hauteur_finale_thumb, $donnees[0], $donnees[1]);//copie avec redimensionnement
imagejpeg ($image_thumb, $content_dir_thumb.$name_file1);
$image_vignette = imagecreatetruecolor($largeur_finale_vignette, $hauteur_finale_vignette); //création image finale
imagecopyresampled($image_vignette, $image, 0, 0, 0, 0, $largeur_finale_vignette, $hauteur_finale_vignette, $donnees[0], $donnees[1]);//copie avec redimensionnement
imagejpeg ($image_vignette, $content_dir_vignette.$name_file1);
}
?>
Il manque un bout de ton deuxième fichier.
Pour répondre :
1 – Tu peux mettre le formulaire et le code php dans le même fichier (il faut juste mettre le formulaire en bas et modifier le paramètre action).
2 – Je pense que cela vient plutôt de la taille (en Mo) de ta photo. Cherche du côté de upload_max_filesize et post_max_size
Merci beaucoup pour ces explications concises et précises !
Je cherchais un script ressemblant à celui-ci pour mon site http://quelfilm.net pour afficher des miniatures de films pour eviter de charger toutes les images taille « réelles ».
Ah oui aussi au passage, pourquoi la fonction imagecopyresampled serait de meilleure qualité que imagecopyresized ??
Encore merci, je reviendrais 😉
La fonction imagecopyresampled utilise un algorithme de meilleure qualité que imagecopyresized (mais est plus lente). Toutes les informations ici : http://fr2.php.net/imagecopyresized#example-3281