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.

php_resize

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!

Vous aimerez aussi...

7 réponses

  1. Thibow dit :

    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.

    • JackPotte dit :

      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.

      • cicoub13 dit :

        Corrigé, merci

        • doni1000 dit :

          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);

          }

          ?>

          • cicoub13 dit :

            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

  2. Rocher dit :

    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 😉

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *