Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Site Web > PHP > Langage, bibliothèques et fonctions > Lecture du tutoriel

[GD] Redimensionner une image sans la déformer

Avatar
Auteur : ratdelabo
Créé : le 21/11/2007 09:54:38
Modifié : le 27/04/2008 21:07:13
Noter et commenter ce tutoriel
Imprimer ce tutoriel
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Ce tutoriel est mon premier et je fais appel, par avance, à votre sollicitude.
Il a pour but de vous exposer une manière de redimensionner une image, en conservant ses proportions largeur / hauteur, de façon à l'insérer proprement dans un de vos scripts (news, diaporama, ...).
Il est bien évident que je ne peux pas présenter ici, pour des raisons de clarté, la construction d'un système complet de news, ou d'une galerie d'images.

Nous commencerons donc par faire un rappel du formulaire qui sera utilisé pour l'upload de l'image. Nous verrons ensuite quelles sont les fonctions qui seront utilisées, en faisant référence à la DOC ;) .

Dans ce tutoriel, j'utiliserai des images au format jpg, jpeg, JPG ou JPEG, en réglant les problèmes de casse, et en vérifiant les extensions (mais proposerai également l'utilisation des gif et png). Vous pourrez donc très facilement adapter ce code à l'utilisation d'autres formats comme gif, png par exemple, à condition de ne pas oublier que certaines fonctions, peu connues, existent : tout le monde emploie imagecreatefromjpeg, mais il existe imagecreatefromgif ou encore imagecreatefrompng (quelques précisions plus bas). Idem pour la fonction imagejpeg qui existe en version imagegif et imagepng ;) .
Il suffira pour vous, d'assurer un minimum de sécurisation des données et de suivre les recommandations pour l'utilisation des autres formats.
Enfin, nous passerons doucement à la pratique. OK ?
Alors c'est parti !
Sommaire du chapitre :

Quelques rappels utiles...

On partira du principe (puisque c'est mon cas) que vous disposez d'un système de news et que vous voulez insérer, pour chacune des nouvelles news, une image ou photo. Mais le problème est de taille : vous avez assuré une mise en page qui vous plaît et la photo est trop grande !
J'affirme encore une fois qu'il s'agit d'un exemple d'utilisation qui ne saurait constituer l'unique façon de mettre à profit ce script !

Comment faire ?

Je vais tout vous dire... don't worry :) .

Commençons par ajouter, à notre formulaire de saisie de news, un espace dédié à l'upload de notre image.
Si vous n'y connaissez rien en insertion de fichier joint à un texte, vous devez absolument faire un tour par .
Je vous rappelle simplement que :
Ah ah ? Compliqué ? Mais non, mais non !
Je vous laisse 2 petites minutes pour réaliser ce petit formulaire minable...

Ça y est ? Alors, correction :
Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<form method="post" action="news.php" enctype="multipart/form-data">
<fieldset class="formulaire_news">
        <p>
                <label for="titre">Titre :</label>
                <input type="text" name="TitreNews" id="titre" />
        </p>
                       
        <p>
                <label for="image">Image : </label>
                <input type="hidden" name="MAX_FILE_SIZE" value="2097152" />
                <input type="file" name="ImageNews" id="image" />
        </p>
                        
        <p>
                <label for="contenu">Contenu :</label>
                <textarea cols="40" rows="3" name="ContenuNews"></textarea>
        </p>
 
        <p>
                <input type="submit" name="InsererNews" value="Insérer" />
                <input type="reset" name="Recommencer" value="Recommencer" />
        </p>
</fieldset>
</form>


J'ai bien évidemment allégé volontairement le formulaire. Vous devriez avoir un auteur en plus, non ?
Vous aurez remarqué que j'appelle une page de traitement que j'ai nommée banalement news.php : vous pouvez la renommer en fonction de vos souhaits.

Voilà, la première sous-partie est terminée.
Si vous avez des soucis de compréhension concernant cette petite mise au point, n'hésitez pas à revenir faire un tour sur le tuto de DHKold.


Maintenant, on passe à la présentation des fonctions que nous utiliserons dans le script de redimensionnement.

Des fonctions très... graphiques

Voici la liste des fonctions que nous utiliserons dans le script de redimensionnement, en partant du principe que vous désirez utiliser une image au format jpg, JPG, JPEG ou jpeg :

Je les ai fait figurer dans l'ordre de leur utilisation dans le script.
L'extension choisie étant jpeg (ou jpg, JPG ou JPEG), deux des fonctions utilisées termineront par jpeg. Mais, comme je vous le répète depuis le début, vous pourrez utiliser les formats png et gif en utilisant lesdites fonctions adaptées (imagecreatefromgif, imagecreatefrompng, et imagegif ou imagepng).
Autant l'array explode et la fonction strtolower peuvent être connues et maîtrisées de vous, autant les autres peuvent paraître "barbares". Mais pas de panique, je vais tout expliquer (dans la mesure de mes compétences, et en m'aidant de la DOC PHP).

L'array explode



explode coupe une chaîne en segments. Il s'agit plus exactement d'une fonction qui retourne un tableau (array) de chaînes issues d'une variable, en utilisant un délimiteur. Oh là ! Doucement, vieux ! C'est compliqué, ton truc !
D'accord, un petit exemple est plus parlant :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
//JE POSE MA VARIABLE :
$variable = "Je veux couper ma variable. Mais je la veux en plusieurs chaînes";
 
//J'UTILISE MON ARRAY EXPLODE :
$chaine = explode('.', $variable);
// MON DELIMITEUR EST LE POINT, MA VARIABLE EST $variable. DONC explode VA COUPER EN CHAINES TOUT CE QUI SE TROUVE DE PART ET D'AUTRE DU POINT.
 
//J'AFFICHE MES CHAINES, DONT LA NUMEROTATION COMMENCE A ZERO ! :
echo $chaine[0]; //CECI VA RETOURNER "Je veux couper ma variable"
echo $chaine[1]; //CECI VA RETOURNER "Mais je la veux en plusieurs chaînes"
?>


L'erreur la plus fréquente est l'inversion des paramètres de l'explode à l'intérieur des parenthèses. Il faut respecter scrupuleusement l'ordre des paramètres, contrairement à implode().


Compris ?

Vous pouvez très bien limiter le nombre de chaînes que vous voulez retourner en utilisant, et ce depuis PHP 4.0.1, le paramètre limit juste avant de fermer la parenthèse.
Exemple : $chaine = explode('.', $variable, 1), auquel cas dans mon exemple précédent, la seule ($limit = 1) chaîne retournée sera : "Je veux couper ma variable".
Depuis PHP 5, il est même possible d'utiliser une limite négative comme -1, et vous verrez plus tard son importance ;) .

La fonction strtolower



Vous vous êtes aperçus bien souvent que les images pouvaient être nommées : jpg / JPG ou encore jpeg / JPEG, gif / GIF ou enfin PNG / png.
Pour éviter tout problème d'interprétation lié à la sensibilité de PHP à la casse, nous utiliserons la fonction strtolower, dont l'effet est de convertir une chaîne en minuscules, sauf les voyelles accentuées. Mais ici, on s'en fiche ^^ .
Cette fonction va nous permettre plus tard de s'assurer de l'extension du fichier à uploader.


La fonction imagecreatefromjpeg



Cette fonction va se montrer déterminante, puisqu'elle va nous permettre de créer une nouvelle image à partir de celle que nous choisirons.
Elle s'utilise très simplement :

Code : PHP
1
2
3
<?php
$NouvelleImage = imagecreatefromjpeg ($ImageChoisie);
?>


Vous pourrez très bien utiliser un chemin de type URL pour votre string $ImageChoisie, à condition d'avoir préalablement activé l'option des "fopen wrappers". Pour cela, il faut aller jeter un oeil ICI.

Cette nouvelle image reste "virtuelle", et nous allons la modifier par la suite.

Remarque 1 : si vous utilisez la fonction équivalente pour les images de format png (imagecreatefrompng), assurez-vous que l'image de départ que vous choisissez ne dépasse pas un nombre total de 1 040 000 pixels, soit une résolution d'environ 1040 x 1000. En effet, la fonction imagecreatefrompng ne semble pas efficiente pour un nombre de pixels supérieur... Allez savoir pourquoi. Là, je sèche !
De plus, si vous travaillez sur des png-24 permettant la transparence, il vous faudra activer le canal alpha et sauvegarder (imagecolorallocatealpha).

Remarque 2 : si vous utilisez la fonction équivalente pour les images de format gif (imagecreatefromgif), vous devez disposer des librairies GD dans leur version inférieure à 1.6, ou supérieure à 2.0.28. Entre ces deux versions, le format n'est pas supporté par GD.

Remarque 3 : les versions Windows de PHP antérieures à la version 4.3.0 ne supportent pas l'accès aux fichiers distants avec ces fonctions, même si allow_url_fopen est activé.


La fonction getimagesize



Pour ceux qui maîtrisent la langue de Shakespeare, ce nom est facile à comprendre :
GET : déterminer, prendre, obtenir ;
IMAGE : ... ;
SIZE : taille.
Cette fonction retourne un array concernant les dimensions de l'image dont les deux premières données nous intéressent particulièrement. Voici comment elle est utilisée simplement :

Code : PHP
1
2
3
<?php
$TailleImage = getimagesize ($ImageChoisie);
?>


Ceci retourne par exemple :

$TailleImage[0] qui correspond à la largeur de l'image (width) et
$TailleImage[1] qui correspond à la hauteur de l'image (height).

On pourrait utiliser également les données suivantes :
$TailleImage[bits], qui nous retourne le nombre de bits, ou encore $TailleImage[mime] qui nous retourne... le type MIME ! Eh oui !

Cette fonction va être utile pour déterminer, au départ, les dimensions de l'image que l'on souhaite redimensionner, mais surtout pour connaître le ratio LARGEUR / HAUTEUR, afin de redimensionner en conservant les proportions ;) . Elle nous servira enfin à vérifier, de manière certaine, le type MIME du fichier uploadé.

Cette fonction ne requiert pas GD.



La fonction imagecreatetruecolor



Cette fonction sera, dans notre exemple, indissociable de la fonction imagecreatefromjpeg.
En effet, imagecreatetruecolor crée une nouvelle image en couleurs vraies, autrement dit, une image noire, dont il faudra préciser la largeur et la hauteur.
Exemple :

Code : PHP
1
2
3
<?php
$ImageEnCouleursVraies = imagecreatetruecolor(800, 600);
?>


Cette nouvelle image en couleurs vraies correspondra en fait à l'ébauche de notre image redimensionnée, ok ?

Remarque : cette fonction ne fonctionne pas avec le format GIF.
De plus, elle requiert la bibliothèque GD 2.0.1 ou supérieure (2.0.28 ou supérieure est recommandée).
Toutefois, il est possible de passer outre cette embûche en utilisant la fonction imagecreate simplement :

Code : PHP
1
2
3
<?php
imagecreate(int x_size, int y_size);
?>




La fonction imagecopyresampled



La fonction magique ! Elle copie, redimensionne et rééchantillonne notre nouvelle image.
Toutefois, son interprétation est un peu plus complexe. Voyons ensemble :

Code : PHP
1
2
3
<?php
imagecopyresampled($NouvelleImage, $ImageDepart, $CoordonneeXduPointdeDestination, $CoordonneeYduPointdeDestination, $CoordonneeXduPointSource, $CoordonneeYduPointSource, $NouvelleLargeur, $NouvelleHauteur, $LargeurImageDepart, $HauteurImageDepart);
?>


Arfff >_< , c'est quoi ce charabia !
Bon, quelques explications s'imposent.


Vous aurez donc compris l'intérêt sans équivoque de l'appel à cette fonction ;) .

Attention : erreur fréquente !
Il arrive fréquemment, lorsque l'on fait appel à cette fonction, de se retrouver avec une image dont les couleurs n'ont plus rien à voir avec celles de l'image de départ : une image toute bleue par exemple.
Pourquoi ? Parce que toutes les couleurs utilisées pour former l'image ne peuvent pas toujours être allouées :'( . La couleur la plus proche (en théorie) est alors utilisée. Je dis bien : en théorie ! Car souvent, ce n'est pas visuellement la couleur la plus proche !
Pour éviter ce genre de déconvenue, il convient d'utiliser la fonction précitée imagecreatetruecolor avant de passer par imagecopyresampled.


La fonction imagedestroy



Bon, eh bien là, c'est clair !
Cette fonction détruit purement et simplement l'image dont on ne veut plus.
Et devinez laquelle ne nous servira plus ?

Réponse ;) ...
L'image originale bien sûr !
Seulement, il faudra utiliser comme string la variable retournée par l'une de nos fonctions précédentes comme imagecreatefromjpeg.
Exemple :

Code : PHP
1
2
3
<?php
imagedestroy($ImageChoisie);
?>


Très difficile, hein ?


La der des der... enfin : la fonction imagejpeg



Cette dernière fonction n'est pas des moins utiles puisqu'elle va nous offrir l'opportunité non seulement de sauvegarder notre nouvelle image dans un fichier, mais également de déterminer la qualité avec laquelle on va l'enregistrer !
Exemple d'utilisation :

Code : PHP
1
2
3
<?php
imagejpeg($NouvelleImage, $fichier, 100);
?>


Ici, je vais sauvegarder ma nouvelle image ($NouvelleImage) dans le fichier choisi ($fichier) avec une qualité maximale (100).

Remarque 1 : le chemin vers le fichier est optionnel. S'il n'est pas défini ou s'il vaut NULL, le flux brut de l'image sera affiché directement. En d'autres termes, l'image GD sera envoyée au format JPEG directement sur la sortie standard (typiquement, votre navigateur Web).
Il en est de même pour la définition de la qualité de l'image sauvegardée. Toutefois, vous pouvez opter pour une qualité allant de 0 (la pire) à 100 (qualité maximale).

Remarque 2 : afin d'utiliser le format jpg avec la fonction imagejpeg, il vous faudra activer la librairie GD 1.8 ou supérieure.
Si vous voulez générer des images JPEG progressives, vous devez activer l'entrelacement à l'aide de la fonction imageinterlace().

Remarque 3 : comme je vous l'ai expliqué plus haut, si votre image est au format png, il faudra utiliser imagepng ; si elle au format gif, il faudra utiliser imagegif ;) .

Eh bien voilà ;) .
Nous en avons fini avec les fonctions utiles à notre script. Vous savez à quoi elles servent. Il ne nous reste plus qu'à les mettre en pratique.
Alors, au boulot !

Redimensionnons, mais sans déformer !

Nous voilà donc plongés dans le vif du sujet !
Pour commencer, reprenons notre formulaire.
Nous avons appelé la page news.php, mais il s'agit en fait de la page que vous utilisez pour traiter en PHP votre formulaire de news. OK ? Donc, vous l'appelez comme bon vous semble.
Dans ce tutoriel, je décide de n'accepter que les images au format jpg ou jpeg, mais je vous montre quand même l'utilisation d'autres formats.
On y va : on récupère notre fichier image envoyé par la méthode POST.

Code : PHP
1
2
3
4
5
6
7
8
9
<?php
if (!empty($_FILES['ImageNews']))
{
  if ($_FILES['ImageNews']['error'] <= 0)
  {
    if ($_FILES['ImageNews']['size'] <= 2097152)
    {
        $ImageNews = $_FILES['ImageNews']['name'];
?>


Ça va jusque-là ? N'oubliez pas qu'il fallait s'assurer, même s'il est fixé par défaut, de ne pas dépasser un poids maximal de 2 Mo pour l'image, soit 2 097 152 octets.
Ok, alors on passe au premier exercice ;) .



Premier exercice : fixer les extensions autorisées des images à uploader



Nous désirons accepter les extensions suivantes (parce que je suis généreux ;) ) :

Mais vous pouvez ajouter ce que vous voulez, dans la mesure où vous réfléchissez ensuite à la manière de les traiter avec les fonctions adéquates.

Comment faire pour s'assurer que l'extension du fichier à uploader est bien une de celles acceptées ?


Je vous laisse réfléchir un peu...
Trouvé ?

Code : PHP
1
2
3
4
5
<?php
//JE CREE UN ARRAY OU SEULES LES EXTENSIONS ACCEPTEES FIGURENT AVEC LE TYPE MIME QUI LEUR EST ASSOCIE, MAIS L'INTERPRETATION PEUT VARIER SOUS IE, ALORS ON LE DIFFERENCIE :
$ListeExtension = array('jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif');
$ListeExtensionIE = array('jpg' => 'image/pjpg', 'jpeg'=>'image/pjpeg'); //IL FALLAIT UNE NOUVELLE FOIS QUE IE SE DIFFERENCIE
?>


Le principe est simple : je crée un tableau d'équivalence dans lequel je précise les extensions que j'accepte avec le type MIME associé en fonction du navigateur, car le type MIME d'un fichier jpg ou jpeg (et seulement ces formats-là) peut être interprété différemment sous IE... Il fallait bien qu'il se distingue une fois de plus, celui-là :colere2: .
Si l'extension de mon fichier est contenue dans l'array, tout est ok, alors on continue, sinon : ERREUR.



Deuxième exercice : vérifier l'extension de notre fichier en utilisant nos array précédents



Idem, je vous laisse deux minutes pour réfléchir.
Attention : 3... 2... 1... partez :) !

Code : PHP
1
2
3
4
5
6
7
8
<?php
// JE VERIFIE L'EXTENSION PRESUMEE DU FICHIER :
$ExtensionPresumee = explode('.', $ImageNews);
$ExtensionPresumee = strtolower($ExtensionPresumee[1]);
if ($ExtensionPresumee == 'jpg' || $ExtensionPresumee == 'jpeg' || $ExtensionPresumee == 'pjpg' || $ExtensionPresumee == 'pjpeg' || $ExtensionPresumee == 'gif' || $ExtensionPresumee == 'png')
{
//ON POURRA ALORS CONTINUER NOTRE VERIFICATION ...
?>



Explications



J'utilise ma première fonction : explode. Je découpe donc $ImageNews en deux chaînes appelées $ExtensionPresumee de part et d'autre du délimiteur '.' (le point) : celle qui contient le nom de l'image (située avant le point), et celle qui contient l'extension (située après le point). Puis, je choisis uniquement de m'intéresser à la chaîne contenant l'extension ; elle est appelée par $ExtensionPresumee[1] (c'est bien la deuxième chaîne puisque la numérotation commence à 0 : vous vous souvenez ?).
Ensuite, je convertis cette extension en minuscules grâce à strtolower, pour éviter les conflits de reconnaissance entre jpg et JPG, ou entre jpeg et JPEG (ou GIF et gif, etc...). Compris ?
Enfin, je vérifie que $ExtensionPresumee corresponde bien à l'une des extensions acceptées.
Mais attention ! Les plus malins me diront :
Citation : Les plus malins
...et si je nomme mon image mon.image.jpg ?
L'explode me renvoie image comme extension ! Et ce n'est pas une extension valide :( .

Bonne remarque effectivement, et merci samuel2202 de m'avoir soumis cette proposition de rectification.
On va donc contourner le problème en comptabilisant (grâce à la fonction count) le nombre total des chaînes retournées par l'explode, et en enlevant 1 au nombre total ;) . En effet, je rappelle que la numérotation des chaînes débute à 0. S'il y a 4 chaînes retournées, la dernière sera donc la [3] (4 - 1 !).
Voici alors le code rectifié :
Code : PHP
1
2
3
4
5
6
7
<?php
$ExtensionPresumee = explode('.', $ImageNews);
$ExtensionPresumee = strtolower($ExtensionPresumee[count($ExtensionPresumee)-1]);
if ($ExtensionPresumee == 'jpg' || $ExtensionPresumee == 'jpeg' || $ExtensionPresumee == 'pjpg' || $ExtensionPresumee == 'pjpeg' || $ExtensionPresumee == 'gif' || $ExtensionPresumee == 'png')
{
//ON POURRA ALORS CONTINUER NOTRE VERIFICATION ...
?>

On poursuit ?



Troisième exercice : vérifier que le type MIME de l'image correspond bien à son extension



Petit rappel : le type MIME, défini depuis 1991, correspond à une information relative au fichier transféré par protocole HTTP, ou par mail. En d'autres termes, lors d'une transaction entre le serveur et le navigateur, le serveur envoie en premier à votre navigateur le type MIME du fichier envoyé.

Je vous demande donc maintenant de vérifier que le type MIME de l'image que vous avez choisie correspond bien à son extension, de façon à éviter des erreurs d'affichage ;) . Vous vous souvenez ici de l'utilité de la fonction getimagesize ?
Attention ! À vos touches, prêts ? Tapez !
...
...
...
Là, vous êtes un peu longs :-° .
Fini ? Non ? Pas trouvé ?
Alors ... :magicien: :

Code : PHP
1
2
3
4
5
<?php
$ImageNews = getimagesize($_FILES['ImageNews']['tmp_name']);
if($ImageNews['mime'] == $ListeExtension[$ExtensionPresumee]  || $ImageNews['mime'] == $ListeExtensionIE[$ExtensionPresumee])
{
?>


Explications



Facile, non ?

Je vous vois d'ici me dire : Citation : Vous
...il est gentil celui-là mais, jusque-là, on n'a toujours pas redimensionné notre image !

Pas de panique, on y arrive. Par contre, à partir de là, et comme ce dossier doit rester un tutoriel, je ne vous exposerai que la façon de redimensionner une image au format jpg, ou jpeg. Il vous faudra donc, si vous voulez utiliser une image png ou gif, faire un petit effort de relecture et d'adaptation. Allez, sourire :) (non, je ne suis pas méchant :colere2: ).


Quatrième exercice : créons notre copie d'image à redimensionner



Pour utiliser une image en vue de la redimensionner, il faut en créer une "sauvegarde", grâce ici, à la fonction imagecreatefromjpeg.
Vous vous souvenez des explications de la partie 2 ?
Vous devrez vous servir du nom temporaire de l'image, récupéré par $_FILES, pour créer votre sauvegarde, et à condition que toutes les conditions précédentes aient été remplies.

Sur ces mots, je vous laisse réfléchir, mes amis ;) ...

Code : PHP
1
2
3
<?php
$ImageChoisie = imagecreatefromjpeg($_FILES['ImageNews']['tmp_name']);
?>


Explications




Rappel : si votre image est un png, vous appliquerez imagecreatefrompng.

Bravo, vous venez de sauvegarder votre image.
Passons à la suite : il nous faut maintenant déterminer les dimensions de notre première image pour pouvoir jouer dessus et redimensionner notre copie.


Cinquième exercice : récupérer les dimensions de l'image de départ



Quelle est la fonction qui permet de récupérer les dimensions d'un fichier posté ?

getimagesize, BRAVO :D !
N'oubliez pas : nous travaillons toujours sur le nom temporaire de l'image choisie ($_FILES['ImageNews']['tmp_name'];), et vous appellerez la nouvelle variable, correspondant à la taille de l'image, $TailleImageChoisie par exemple.
Vous avez 1 minute montre en main :pirate: ...

Code : PHP
1
2
3
<?php
$TailleImageChoisie = getimagesize($_FILES['ImageNews']['tmp_name']);
?>


Bon là, il n'y a pas grand-chose à expliquer... Tout est clair, non ?

Eh bien ! Vous avez fait du chemin d'un coup !
Récapitulons :

Il nous faut donc maintenant préciser les nouvelles dimensions que nous souhaitons appliquer à la future image (celle qui sera redimensionnée).


Sixième exercice : tailler la nouvelle image



Plusieurs choix s'offrent ici à nous :

Mais pour cela, il faudra, avant de pouvoir afficher la hauteur proportionnellement à la largeur, trouver le ratio LARGEUR / HAUTEUR de la première image, pour l'appliquer ensuite à la nouvelle taille ;) .
Quelles fonctions allez-vous utiliser ?

Aucune ! :p C'était un piège... Il nous faudra juste appliquer des chiffres ou des calculs simplissimes.
Au boulot, jeunes gens.

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
//Etape 1 :
$NouvelleLargeur = 350;
 
//Etape 2 :
$Reduction = ( ($NouvelleLargeur * 100)/$TailleImageChoisie[0] );
 
//Etape 3 :
$NouvelleHauteur = ( ($TailleImageChoisie[1] * $Reduction)/100 );
?>


Explications



Créons de suite la nouvelle image en lui appliquant les nouvelles dimensions, celles que nous venons de trouver.


Septième exercice : création de la "miniature"



Alors, que faire... Si vous revenez un instant sur la liste des fonctions que nous devions utiliser, vous pourriez déjà en barrer un paquet :

Rappels : la fonction imagecreatetruecolor doit faire suite à la fonction imagecreatefromjpeg, tandis que la fonction imagecopyresampled sert à rééchantillonner l'image de départ en la nouvelle image désirée.
Donc, d'abord imagecreatetruecolor, puis imagecopyresampled.

Vous devriez avoir déjà fini :colere: ! Que faites-vous à attendre, là ? Codez !!

Code : PHP
1
2
3
4
5
6
7
<?php
//Etape 1 :
$NouvelleImage = imagecreatetruecolor($NouvelleLargeur , $NouvelleHauteur) or die ("Erreur");
 
//Etape 2 :
imagecopyresampled($NouvelleImage , $ImageChoisie, 0, 0, 0, 0, $NouvelleLargeur, $NouvelleHauteur, $TailleImageChoisie[0],$TailleImageChoisie[1]);
?>


Explications



Eh bien mes amis, nous en avons presque fini avec le redimensionnement de notre image ;) .

Pourquoi conserver l'image initiale, alors qu'elle ne nous sert plus à rien ?

Bonne question. La réponse est simple : vous pouvez vous en servir pour l'afficher en taille "réelle" lorsque votre miniature est une image cliquable (exemple d'un diaporama).
Ici, il n'y a donc qu'une chose à faire : la supprimer, puisque nous ne nous servirons pas d'images cliquables (dans mon exemple).

Allez, encore quelques efforts de mémoire.

Quelle fonction nous permet de supprimer un fichier image dont on ne veut plus ?

imagedestroy, BRAVO :) !

Vous vous souvenez de notre copie de sauvegarde de notre image ? Celle que l'on a nommée $ImageChoisie, et que l'on a obtenue grâce à la fonction imagecreatefromjpeg ?
Eh bien, vous allez vous en servir, parce que c'est elle qu'il faut supprimer !
Allez, je vous attends :soleil: ...

Code : PHP
1
2
3
<?php
imagedestroy($ImageChoisie);
?>


Résumons un peu, maintenant.
Nous avons jusqu'ici choisi une image à redimensionner, déterminé ses dimensions, créé une copie de sauvegarde de cette image, redimensionné l'image comme voulu, rééchantillonné l'image pour pouvoir l'utiliser, et détruit l'image choisie au départ pour éviter de surcharger le serveur.
Notre travail est donc terminé. YOUPI !!!

Mais les plus attentifs me diront que nous n'avons pas utilisé la fonction imagejpeg, dont nous avions parlé dans la seconde sous-partie. Elle n'intervient pas dans le redimensionnement mais dans l'enregistrement du fichier dans un dossier spécifique. Et comme je suis très gentil, je vais vous montrer, en bonus, comment utiliser cette dernière fonction et ainsi enregistrer notre image redimensionnée dans un dossier précis de votre serveur ;) .



Bonus : enregistrer notre nouvelle image grâce à imagejpeg



Nous allons suivre ici la logique adoptée depuis le début, mais on va, en plus, sécuriser le nom de l'image grâce à une fonction supplémentaire. Le but de cette démarche sera d'éviter les doublons de noms lors de l'insertion (obtenir un nom unique), et d'éviter également les problèmes de sécurité liés à la conservation du nom de l'image lors de l'envoi.


Retrouver le nom de l'image en utilisant explode



Une nouvelle fois, explode va se montrer fort utile. Tout ce que nous voulons, c'est supprimer (provisoirement) l'extension de notre image pour ne conserver que son nom. Alors, c'est du gâteau, n'est-ce pas ?
Je pars du principe que je modifie le nom original de l'image de départ, récupérée par $_FILES, et que j'ai nommée au début $ImageNews.


Code : PHP
1
2
3
<?php
$NomImageChoisie = explode('.', $ImageNews);
?>



Modifier le nom retrouvé pour sécuriser notre insertion



Je crée donc une variable $NomImageExploitable, correspondant au nom dont je vais me servir pour appeler définitivement mon image. C'est elle qui sera "cryptée" numériquement. Pour cela, il faudra, par exemple, utiliser la fonction time(); (mais la fonction microtime(); peut également être utilisée ;) ).

Code : PHP
1
2
3
<?php
$NomImageExploitable = time();
?>


Petite explication au passage
Il est préférable, pour alléger le code, d'écrire :

Code : PHP
1
2
3
<?php
$NomImageExploitable = time();
?>


plutôt que :

Code : PHP
1
2
<?php
$NomImageExploitable = time($NomImageChoisie[0]);


puisque le nom original de l'image ne nous sert ici plus à rien (ben oui, on le "crypte" ;) ).


Finir en enregistrant la nouvelle image dans le dossier de notre choix, tout en choisissant sa qualité



C'est ici que nous allons utiliser notre dernière fonction, imagejpeg, en stipulant le nom de la variable 'nouvelle image' ($NouvelleImage), la dénomination de celle-ci ($NomImageExploitable) et son extension ($ExtensionPresumee), et finalement la qualité de rééchantillonnage (valeur numérique de 0 à 100).

Code : PHP
1
2
3
<?php
imagejpeg($NouvelleImage , 'imagesnews/'.$NomImageExploitable.'.'.$ExtensionPresumee, 100);
?>


Explications
J'ai choisi un dossier fictif nommé imagesnews. Je détermine l'extension de mon image redimensionnée grâce au paramètre de l'array $ExtensionPresumee.
Je l'enregistre avec une qualité de 100 (qualité maximale). Mais bien souvent, une valeur de 80 suffit amplement ;) .
Voilà, votre image redimensionnée est enregistrée dans le dossier imagesnews, avec une qualité de 100, et des dimensions choisies.

Pour finir, une petite devinette.
Comment insérer un lien relatif dans ma bdd, et récupérer cette image facilement dans mes news ?

Je crée une variable $LienImageNews qui vaudra le chemin relatif vers la nouvelle image :

Code : PHP
1
2
3
<?php
$LienImageNews = 'imagesnews/'.$NomImageExploitable.'.'.$ExtensionPresumee;
?>


Puis, je l'insère dans ma page ;) .


Extra-Bonus : code possible pour l'utilisation d'une image jpg, JPG, jpeg ou JPEG



N'oubliez pas de vous référer au code de notre formulaire d'insertion de la première sous-partie, pour comprendre l'utilisation des variables. J'évite volontairement la connexion à la BDD, parce que chacun a sa propre méthode (en dur dans le code, en include...).

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
if (!empty($_POST['InsererNews']))
{
        $ListeExtension = array('jpg' => 'image/jpeg', 'jpeg'=>'image/jpeg');
        $ListeExtensionIE = array('jpg' => 'image/pjpeg', 'jpeg'=>'image/pjpeg');
        if (!empty($_POST['TitreNews']) && (!empty($_FILES['ImageNews'])) && (!empty($_POST['ContenuNews'])))
        {
                $TitreNews = $_POST['TitreNews'];
                $ContenuNews = $_POST['ContenuNews'];
 
                if ($_FILES['ImageNews']['error'] <= 0)
                {
                        if ($_FILES['ImageNews']['size'] <= 2097152)
                        {
                            $ImageNews = $_FILES['ImageNews']['name'];
 
                            $ExtensionPresumee = explode('.', $ImageNews);
                            $ExtensionPresumee = strtolower($ExtensionPresumee[count($ExtensionPresumee)-1]);
                            if ($ExtensionPresumee == 'jpg' || $ExtensionPresumee == 'jpeg')
                            {
                              $ImageNews = getimagesize($_FILES['ImageNews']['tmp_name']);
                              if($ImageNews['mime'] == $ListeExtension[$ExtensionPresumee]  || $ImageNews['mime'] == $ListeExtensionIE[$ExtensionPresumee])
{
 
                                              $ImageChoisie = imagecreatefromjpeg($_FILES['ImageNews']['tmp_name']);
                                              $TailleImageChoisie = getimagesize($_FILES['ImageNews']['tmp_name']);
                                              $NouvelleLargeur = 350; //Largeur choisie à 350px mais modifiable
 
                                              $Reduction = ( ($NouvelleLargeur * 100)/$TailleImageChoisie[0] );
                                              $NouvelleHauteur = ( ($TailleImageChoisie[1] * $Reduction)/100 );
 
                                              $ImageChoisie = imagecreatefromjpeg($_FILES['ImageNews']['tmp_name']);
                                              $NouvelleImage = imagecreatetruecolor($NouvelleLargeur , $NouvelleHauteur) or die ("Erreur");
 
                                              imagecopyresampled($NouvelleImage , $ImageChoisie  , 0,0, 0,0, $NouvelleLargeur, $NouvelleHauteur, $TailleImageChoisie[0],$TailleImageChoisie[1]);
                                              imagedestroy($ImageChoisie);
                                              $NomImageChoisie = explode('.', $ImageNews);
                                              $NomImageExploitable = time();
                                              
                                              imagejpeg($NouvelleImage , 'imagesnews/'.$NomImageExploitable.'.'.$ExtensionPresumee, 100);
                                              $LienImageNews = 'imagesnews/'.$NomImageExploitable.'.'.$ExtensionPresumee;
 
                                              $sql= 'INSERT INTO votre_table VALUES ("", "'.$TitreNews.'", "'.$ContenuNews.'", "'.$LienImageNews.'", "'.time().'")';
                                              $res = mysql_query($sql) or die(mysql_error());
                                              if ($res)
                                              {
                                                      echo 'La news a bien été insérée';
                                              }
                                        }
                                        else
                                        {
                                                echo 'Le type MIME de l\'image n\'est pas bon';
                                        }
                                }
                                else
                                {
                                        echo 'L\'extension choisie pour l\'image est incorrecte';
                                }
                        }
                        else
                        {
                                echo 'L\'image est trop lourde';
                        }
                }
                else
                {
                        echo 'erreur lors de l\'upload image';
                }
        }
        else
        {
                echo 'Au moins un des champs est vide';
        }
}
?>


Je n'ai pas sécurisé les données !

J'ai effectué une simple vérification des données concernant l'image. Il vous faudra vérifier les autres variables.
Par exemple, passez $TitreNews, $ContenuNews par un mysql_real_escape_string, htmlspecialchars et trim...
Vérifiez que le nom de vos fichiers ne contient pas d'espace superflu qui pourrait bloquer la vérification...
Etc.
De plus, il vous faudra assurer basiquement la connexion à votre base de données ;) .

Voilà, c'est fini (ça me rappelle une chanson, ça ! ).
En espérant que ce tuto vous a appris 2 ou 3 petites choses et surtout, qu'il vous servira.
Vous aurez remarqué que ce script n'apporte pas une sécurité optimale (faille du byte NULL par exemple ;) ).
De plus, il serait préférable, quand cela est possible, d'utiliser la fonction system ou shell_exec pour connaître le type MIME du fichier de façon un peu plus certaine.

Je tiens enfin à remercier tout particulièrement mon grand ami inazo, sans qui rien n'aurait été possible ;) .

P.S. : j'ai choisi ici de détruire l'image source, mais il vous est possible de la conserver sous un nom facilement identifiable pour permettre son affichage simultané.
Exemple :

Code : PHP
1
2
3
4
5
6
7
<?php
//Enregistrement de l'image redimensionnée :
imagejpeg($NouvelleImage , 'imagesnews/'.$NomImageExploitable.'.'.$ExtensionPresumee, 100);
 
//Enregistrement de l'image initiale :
imagejpeg($ImageChoisie , 'imagesnews/'.$NomImageExploitable.'FullImage.'.$ExtensionPresumee, 100);
?>


Intérêt ?
Vous conservez l'image de départ et sa miniature, et vous créez votre diaporama facilement :D .

Je vous remercie d'avoir suivi ce tutoriel, mon premier, jusqu'au bout ; et je suis très impatient de répondre à vos critiques.

Cordialement,
ratdelabo
Auteur : ratdelabo
Noter et commenter ce tutoriel
Imprimer ce tutoriel

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 426 Zéros connectés | Requêtes SQL 7 requêtes | Temps de génération de la page : Total (SQL) 0.0222s (0.0107s)