Réduire et redimensionner des images en PHP

Si je ne devais citer qu’un seul défaut de PHP, ce serait son incohérence. Les noms de fonctions manquent de logique, l’ordre des arguments n’est jamais le même, et la liste pourrait continuer longtemps encore… Voici quelques informations à connaître pour travailler avec les images.

1. Ouvrir l’image

Les fonctions s’appliquant aux images demandent une ressource (resource en anglais) qui est un type particulier de variable. Attention à bien nommer vos variables, pour passer le bon type aux fonctions !


// Déterminer l'extension à partir du nom de fichier
$extension = substr( $img_src_chemin, -3 );
// Afin de simplifier les comparaisons, on met tout en minuscule
$extension = strtolower( $extension );

Ouvrir l’image avec la fonction appropriée en fonction de l’extension :


switch ( $extension ) {

case "jpg":
case "peg": //pour le cas où l'extension est "jpeg"
$img_src_resource = createimagefromjpeg( $img_src_chemin );
break;

case "gif":
$img_src_resource = createimagefromgif( $img_src_chemin );
break;

case "png":
$img_src_resource = createimagefrompng( $img_src_chemin );
break;

// On peut également ouvrir les formats wbmp, xbm et xpm (vérifier la configuration du serveur)

default:
echo "L'image n'est pas dans un format reconnu. Extensions autorisées : jpg/jpeg, gif, png";
break;
}

Pour ouvrir une image, il faut passer par une fonction dont le nom commence par create. Pensez ce que vous voulez, mais pour moi c’est tout sauf intuitif…

2. Créer l’image de destination

Il n’est pas recommandé de modifier directement l’image sur laquelle vous travaillez, il nous faut donc créer une ressource vide, dans laquelle sera enregistré le flux (stream) contenant l’image modifiée. Il est également recommandé de créer une ressource en mode « couleurs réelles ». Cela évite que les recalculs soient limités par une palette de 255 couleurs et permet d’obtenir un bien meilleur rendu.


//Pour créer une image de destination de 100 pixels de large sur 200 de haut
$img_dst_resource = imagecreatetruecolor( 100, 200 );

3. Redimensionner

Deux fonctions permettent de redimensionner une image, imagecopyresized et imagecopyresampled. La première est plus rapide mais moins précise et donne un résultat moins fin. Toutes deux demandent les 10 paramètres suivants :

  1. L’image de destination (une ressource, pas un chemin),
  2. L’image d’origine (une ressource aussi),
  3. Les coordonnées horizontales du point où commencer l’écriture,
  4. Les coordonnées verticales du point où commencer l’écriture,
  5. Les coordonnées horizontales du point où commencer la lecture,
  6. Les coordonnées verticales du point où commencer la lecture,
  7. La largeur de l’image de destination,
  8. La hauteur de l’image de destination,
  9. La largeur de l’image d’origine,
  10. La hauteur de l’image d’origine.

Pour recopier une image sans décalage, mettre 0 pour les paramètres 3 à 6.

Les dimensions d’une image peuvent s’obtenir à l’aide des fonctions imagesx() et imagesy(), ou encore par getimagesize(). Les deux premières fonctions demandent une ressource, la dernière en revanche demande une chaîne de texte contenant le chemin de l’image.


// Exemple avec imagesx() et imagesy()
$img_src_width = imagesx( $img_src_ressource );
$img_src_height = imagesy( $img_src_ressource );

// Exemple avec getimagesize()
// getimagesize renvoie un tableau
// Ce tableau contient la largeur, la hauteur, un entier représentant le type d'image, et
// une chaîne width/height pouvant être insérée dans une balise img.
// Je vous laisse lire la documentation pour les détails techniques
list( $img_src_width, $img_src_height ) = getimagesize($img_src_chemin);

4. Enregistrer l’image modifiée

Le plus dur est fait, il ne reste plus qu’à enregistrer le flux contenant l’image redimensionnée. Si vous avez déjà travaillé avec des fichiers en PHP, désolé mais ça ne vous avancera pas beaucoup. En effet, on ne peut pas enregistrer telle quelle une ressource image, il faut utiliser une fonction particulière, en fonction du type d’image souhaité.


// Vérifions tout d'abord que nous pouvons enregistrer le fichier
$handle = fopen( $img_dst_chemin, "w" );
if ( !$handle ) {
echo "Impossible d'écrire l'image. Vérifiez le chemin, et les droits du serveur.";
exit;
}
fclose( $handle );

// Pour enregistrer au format jpg
imagejpeg( $img_dst_ressource, $img_dst_chemin );
// Un troisième argument, facultatif, est la qualité. Elle est de 75 par défaut.

// Pour enregistrer au format png
imagepng( $img_dst_ressource, $img_dst_chemin );

// Pour enregistrer au format gif
imagegif( $img_dst_ressource, $img_dst_chemin );

// Pour enregistrer au format wbmp
imagewbmp( $img_dst_ressource, $img_dst_chemin );

Et voilà ! J’ai rassemblé tout le code dans un fichier (redimensionner.phps, en pièce jointe) mais je vous laisse l’adapter, c’est la meilleure façon d’apprendre.

Publié le Catégories BlogMots-clés

15 réflexions au sujet de « Réduire et redimensionner des images en PHP »

  1. Bonjour !
    Est il nécessaire d’utiliser des librairies spéciales pour utiliser
    ces fonctions sur un site web par exemple ?

    Merci

  2. @Lemessager : Bonne question. Les fonctions utilisées ici font parties de la librairie GD, disponible sur la plupart des hébergeurs. Pour savoir si vous avez accès à ses fonctions, regardez les différentes librairies disponibles grâce à phpinfo ou, si vous n’y avez pas accès, en utilisant GD_info.

  3. J’ai un soucis j’ai adapté ce code, le probleme c’est que ce script me cré une image du nom demandé le meme nom que le fichier source dans un repertoire différent ce qui est jusque la normal..

    Mais en regardant de plus pres il y a un probleme (pas d’erreur PHP ni code, ni warning ni autres..)
    mais en fait il ma créé une image dnas le bon repertoir ave cle bon nom mais celle ci pese 0octet
    kan je veux l’afficher il me met une croix rouge et kan je la download du FTP il n’y a rien le fichier n’apparait pas il est present mais inexistant..
    seriez vous quelle en est la rasion??
    merci

  4. @Kreat-X Studio : Etrange en effet. Le code que je présente dans ce billet détaille les différentes opérations à effectuer pour manipuler les images avec GD. Je ne peut pas deviner dans quelle mesure tu l’as adapté, ce qui rend la résolution du problème un peu difficile… Je peut néanmoins te proposer les pistes suivantes :

    • Vérifie que la librairie GD est bien installée (cf ma réponse au premier commentaire)
    • Vérifie que les droits de lecture et d’écriture sont corrects (le serveur doit pouvoir lire l’image d’origine et écrire la nouvelle)
    • Vérifie également que l’image d’origine s’affiche bien quand tu l’appelle du serveur via ton navigateur (pour information quand on re-soumet un formulaire d’upload avec F5/rafraîchir la page, le fichier n’est pas renvoyé)

    Je veux bien jeter un oeil au code adapté mais je serais en vacances la semaine prochaine donc je risque de ne pas pouvoir te répondre tout de suite.

  5. Je pense que, dans la partie 2, il doit s’agir de
    $img_dst_ressource
    avec deux ‘s’, puisque les variables sont abrégées en
    français.

    Bonne journée.

  6. Salut
    1- il faut remplacer createimage… par imagecreate….
    2 – ressource ou resource, il faut effectivement choisir
    3 – pour que ça fonctionne il faut ajouter header (content-type :image/jpeg) en tête de programme
    4 – mon souci est que je n’arrive pas à cumuler ce prog avec un affichage du style echo ‘ ça s’est bien passé’; même en cumulant des header dans tous les sens.

    As tu une solution …
    @ bientôt
    E.T.

  7. Bonjour,

    Je viens de créer ce script :

    ———————————————————-

    if ($_FILES[‘Filedata’][‘name’])
    {
    $uploadIco = $_REQUEST[‘dir’]. »/icones/ »;
    $img_src_chemin = $uploadIco . basename($_REQUEST[‘fileName’]);
    $img_dst_chemin = $uploadIco . basename($_REQUEST[‘fileName’]);
    $img_src_resource = imagecreatefromjpeg( $img_src_chemin );
    $img_dst_resource = imagecreatetruecolor(75,75);
    $img_src_width = imagesx( $img_src_resource );
    $img_src_height = imagesy( $img_src_resource );
    imagecopyresampled($img_dst_resource,$img_src_resource,0,0,0,0,75,75,$img_src_width,$img_src_height);
    imagejpeg( $img_dst_resource, $img_dst_chemin);
    }

    ———————————————————-

    Ici les images viennent par lot.
    je fait un upload multifichier via flash

    donc ce script s’execute jusqu’à ce qu’il n’y ai plus d’image à redimmensionner et à uploader.

    Les parametres :
    * $_REQUEST[‘dir’] -> Répertoire transmis par un fichier flash
    * basename($_REQUEST[‘fileName’]); -> Nom des fichiers transmis par un fichier flash.

    MON SOUCIS :

    En fait tout ce passe à merveille.
    Seul problème, je dispose donc après l’execution du script de minature de 75 x 75 px mais l’image est toute noir. comme ci il ne l’avait pas copié dans la zone temporaire..

    Quelqu’un peut il m’apporter son aide ?
    Merci

  8. PROBLEME PRECEDENT RESOLU. Merci

    ——————-

    La ligne :
    $img_src_chemin = $uploadIco . basename($_REQUEST[‘fileName’]);

    a été remplacée par la ligne :
    $img_src_chemin = $_FILES[‘Filedata’][‘tmp_name’];

    —————–

    Bien à vous.
    Ciao

  9. Le terme « create » est employé parce que la fonction *crée* une ressource. Il ne s’agit pas d’une simple ouverture de fichier et il convient de le faire apparaître dans le nom de l’instruction.

  10. bon… pourquoi ne donnez-vous pas d’exemple concret ?

    On prend une image départ au dimension X, Y

    On veut la redimensionner avec une hauteur de 200px

    On utilise et imagecopyresampled en faisant :

    et là expliquer la fonction…

    Du coup moi… ben je n’ai toujours rien compris… dommage….

    bon je continue à chercher.. mais entre chemin, ressource etc … dingue…

  11. bjr tout le monde j voulai juste savoir si j peux reduire juste le poids d une image (Ko) sana changé les valeurs d origines de la largeur eu la hauteur (en php bien sur )

  12. ouch!!! à peine arrivé sur le site je repars aussi tôt ! 🙂 je laisse tout de même un commentaire pour dire pourquoi vue que je ne suis certainement pas le seul.

    Lorsque je vois des bouts de codes en aussi petit caractère ainsi qu’une taille de police générale aussi peu ergonomique et donc ILLISIBLE je fuis aussi tôt.

    Pourquoi il y a t-il autant de site qui manque à ce point d’ergonomie des fautes impardonnable à l’heure actuelle car le design reste sobre mais une taille de caractère si petite ? c’est pour rendre aveugle ?

    enfin voilà j’espère que ca servira à quelque chose 😉

  13. @zac : peut-être parce que beaucoup de gens utilisent les thèmes par défaut ? Et que beaucoup de gens ne lisent plus sur les sites mais dans le confort de leur agrégateur ?

    Je prends note de la critique cependant, et je me bouge pour rendre le thème de ce blog plus lisible et plus ergonomique.

  14. Salut Goulven et merci pour ton blog.

    Cependant dans l’extraction de l’extension d’un fichier, il y a un petit souci. Si l’extension fait plus de 3 caractères, tu en perds.

    Je pense qu’il est donc plus prudent de faire :

    $extensionDuFichier = mb_strtolower(substr(strrchr($nomDuFichier, ». »),1));

    Si cela peut servir !

    A bientôt

Les commentaires sont fermés.