Gérer les images en PHP
Même si la spécialité de PHP est la génération dynamique de contenu (html,css), il peut aussi créer et manipuler des images.
PHP propose une bibliothèque GD pour gérer les images. GD supporte un grand nombre de format. Il est conseillé de créer des images au format jpg ou png, car le gif n’est pas disponible entre les versions GD 1.6 et GD 2.0.28.
Information d’en-tête
Avant la création d’une image vous devez spécifier son type mine (par exemple une image ‘jpg’) avec la fonction header().
<?php
header("Content-type: image/jpeg");
?>
Pour le format ‘png’ la valeur est ‘image/png’.
Créer une image vide
La fonction imagecreatetruecolor() permet de créer une image en vraies couleurs. Elle retourne un identifiant de ressource d’image en cas de succès, ou FALSE si une erreur survient. Il faut fournir en argument les dimensions de l’image.
<?php
header("Content-type: image/jpeg");
// création de l'image
$image = imagecreatetruecolor(200,100);
// affichage de l'image
imagejpeg($image);
?>
La fonction imagejpeg() affiche l’image créée (de dimension 200×100 pixels). Cette image sera remplie par défaut d’une couleur noire.
Couleur de remplissage
Pour remplir l’image d’une couleur différente il faut d’abord définir cette couleur avec la fonction imageolorallocate() qui prend en paramètre la ressource de l’image et la couleur notée en RVB (les paramètres correspondent aux composantes Rouge, Vert et Bleu, qui sont trois valeurs comprises entre 0 et 255). Dans cet exemple la couleur de fond est le bleu.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
// Alloue la couleur bleu
$bleu = imagecolorallocate($im, 0, 0, 255);
?>
Il faut ensuite utiliser une fonction de remplissage imagefill() qui prend en paramètre la ressource de l’image, le point de départ en x et y , et la couleur de remplissage.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
// Fixe le fond bleu
imagefill($image, 0, 0, $bleu);
imagejpeg($image);
?>
Les fonctions de dessin
La fonction imageellipse() permet de dessiner une ellipse. Elle prend en paramètre, la ressource de l’image, son centre (valeur en x et y), la largeur, la hauteur, et la couleur de contour.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurEllipse = imagecolorallocate($image, 255, 0, 0);
// On dessine l'ellipse
imageellipse($image, 100, 50, 100, 70, $couleurEllipse);
imagejpeg($image);
?>
Pour dessiner une ellipse pleine, utilisez la fonction imagefilledellipse(), qui est semblable à la précédente hormis le dernier paramètre qui représente la couleur de fond de l’ellipse.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurEllipse = imagecolorallocate($image, 255, 0, 0);
// On dessine l'ellipse
imagefilledellipse($image, 100, 50, 100, 70, $couleurEllipse);
imagejpeg($image);
?>
La fonction imagearc() permet de dessiner une ellipse partielle. Elle prend en paramètre, la ressource de l’image, son centre (valeur en x et y), la largeur, la hauteur, l’angle de début, l’angle de fin.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'arc
$couleurArc = imagecolorallocate($image, 255, 0, 0);
// On dessine l'arc
imagearc($image, 100, 50, 100, 70, 0, 180, $couleurArc);
imagejpeg($image);
?>
0° correspond à la position « trois heures » et l’ellipse est dessiné dans le sens des aiguilles d’une montre.
La fonction imagerectangle() permet de dessiner un rectangle. Elle prend en paramètre la ressource de l’image, le point x et y du coin supérieur gauche, le point x et y du coin inférieur bas, et la couleur de contour.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurRect = imagecolorallocate($image, 255, 0, 0);
// On dessine l'ellipse
imagerectangle($image, 25, 25, 175, 75, $couleurRect);
imagejpeg($image);
?>
Pour dessiner un rectangle plein, utilisez la fonction imagefilledrectangle(), qui est semblable à la précédente hormis le dernier paramètre qui représente la couleur de fond du rectangle.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurRect = imagecolorallocate($image, 255, 0, 0);
// On dessine l'ellipse
imagefilledrectangle($image, 25, 25, 175, 75, $couleurRect);
imagejpeg($image);
?>
La fonction imagepolygon() permet de dessiner un polygone. Elle prend en paramètre la ressource de l’image, un tableau contenant les sommets du polygone (en x et y), le nombre de sommets et la couleur de contour.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurPoly = imagecolorallocate($image, 255, 0, 0);
// On dessine le polygone
imagepolygon($image, array(
10, 10,
150, 50,
30, 75
),
3,
$couleurPoly);
imagejpeg($image);
?>
Pour dessiner un polygone plein, utilisez la fonction imagefilledpolygon(), qui est semblable à la précédente hormis le dernier paramètre qui représente la couleur de fond du polygone.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour l'ellipse
$couleurPoly = imagecolorallocate($image, 255, 0, 0);
// On dessine le polygone
imagefilledpolygon($image, array(
10, 10,
150, 50,
30, 75
),
3,
$couleurPoly);
imagejpeg($image);
?>
Autres fonctions de dessin
La bibliothèque GD propose encose d’autre fonctions présentées ci-dessous :
- La fonction ImageSetStyle($image, $style) : permet de changer le style de tracé des lignes
- La fonction ImageSetBrush ($image, $brush) : permet de changer la brosse pour le dessin des lignes
- La fonction ImageSetPixel ($image, $x, $y, $couleur) : dessine dans $image un point de coordonnées ($x,$y) et de couleur $couleur
- La fonction ImageSetThickness ($image, $epaisseur) : Change l’epaisseur des lignes tracées par toutes les fonctions.
Dessiner du texte
Il est possible de dessiner du texte horizontale dans une image avec la fonction imagestring(). Cela peut s’avérer utile pour signer l’image ou pour rajouter des légendes sur l’image s’il s’agit d’un graphe ou d’un histogramme, par exemple.
Cette fonction prend en paramètre la ressource de l’image, une font (peut être 1, 2, 3, 4, 5 pour les polices internes d’encodage Latin2 ou chargée par la fonction imageloadfont() – voir plus bas ) la position en x et y du texte, la chaîne à écrire et la couleur du texte.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour le texte
$couleurText = imagecolorallocate($image, 255, 0, 0);
// On dessine l'image
imagestring($image, 5, 100, 50, "Daniel", $couleurText);
imagejpeg($image);
?>
Si vous utiliser l’encodage UFT-8 pour vos textes, pensez à utiliser la fonction utf8_decode() pour les caractères accentués.
<?php
header("Content-type: image/jpeg");
$image = imagecreatetruecolor(200,100);
$bleu = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $bleu);
// Alloue la couleur rouge pour le texte
$couleurText = imagecolorallocate($image, 255, 0, 0);
// On dessine l'image, on décode les accents
imagestring($image, 5, 100, 50, utf8_decode("C'est l'été"), $couleurText);
imagejpeg($image);
?>
Vous pouvez dessiner une chaîne verticale avec la fonction imagestringup() qui fonctionne avec les mêmes paramètres que la fonction imagestring().
Charger un nouvelle police
La fonction imagettftext() permet de dessiner un texte avec une police TrueType (.ttf).
Cette fonction prend en paramètre la ressource de l’image, la taille de la police, l’angle de lecteur (zéro pour une lecture normal, une valeur de 90 correspondra à une lecture du texte de bas en haut), les coordonnées données par x et y définiront la position du premier caractère (le coin bas-gauche du caractère), la couleur du texte, le chemin vers la police TrueType, et la chaîne à écrire en UTF-8.
<?php
header('Content-Type: image/png');
$image = imagecreatetruecolor(200, 100);
// Création de quelques couleurs
$blue = imagecolorallocate($image, 0, 0, 255);
$red = imagecolorallocate($image, 255, 0, 0);
imagefilledrectangle($image, 0, 0, 200, 100, $blue);
// Le texte à dessiner
$text = 'Daniel...';
// Le chemin de police
$font = 'Amadeus.ttf';
// Ajout du texte
imagettftext($image, 20, 0, 30, 50, $red, $font, $text);
// Utiliser imagepng() donnera un texte plus claire qu'avec fonction imagejpeg()
imagepng($image);
?>
Créer une image depuis un fichier
Il existe des fonctions pour charger le contenu d’un fichier image dans une image vide.
Ces fonctions sont très utilisées pour protéger vos images en rajoutant une signature ou un copyright.
Ces fonctions sont aussi très utiles pour générer des miniatures (voir plus bas).
La fonction ImageCreateFromJpeg() permet de lire une image existante. Elle prend en paramètre le chemin vers l’image JPEG. Cette fonction retourne un identifiant de ressource d’image en cas de succès, ou FALSE si une erreur survient.
<?php
header('Content-Type: image/jpeg');
// chemin de l'image
$source = "animals-q-c-200-150-8.jpg";
// lecture de l'image
$photo = ImageCreateFromJpeg($source);
// affichage de l'image
imagejpeg($photo);
?>
Enregistrer une image
Pour enregistrer votre image sur votre serveur, il suffit d’indiquer en deuxième paramètre d’une des fonctions d’affichage (imagejpeg(), par exemple) le chemin de la nouvelle image.
<?php
header('Content-Type: image/jpeg');
// chemin de l'image
$source = "animals-q-c-200-150-8.jpg";
// lecture de l'image
$photo = ImageCreateFromJpeg($source);
// enregistrement de l'image
imagejpeg($photo,"images/petitChien.jpg");
?>
Dans cet exemple, le flux d’image ne sera pas afficher, l’image source sera enregistrer sous un nouveau nom.
Enregistrer une image en base 64
Il est possible d’encoder un fichier (une image ou autre..) en un chaîne de caractères. L’intérêt est de pouvoir stocker cette imge dans un fichier texte ou dans une base de données.
Il faut d’abord lire la source de l’image avec la fonction file_get_contents() qui lit le fichier dans une chaîne et utiliser la fonction base64_encode() qui va encoder cette chaîne en MIME base64.
<?php
header('Content-Type: image/jpeg');
// chemin de l'image
$source = "animals-q-c-200-150-8.jpg";
// lecture de l'image
$imageString = file_get_contents($source);
//encodage en base MIME base64
echo base64_encode($imageString);
?>
Affichage
/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2Qtan....
Le poids d’une image en base 64 sera plus important (33% de plus) que celui de départ.
Afficher une image en base 64
Si l’affichage est gérer par PHP, il faut utiliser la fonction imagecreatefromstring() qui crée une image à partir d’une chaîne mais il faut d’abord décoder la chaîne en MIME base64 avec la fonction base64_decode().
<?php
header('Content-Type: image/jpeg');
// image encodée
$data64 = "/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2Qtan....";
// décodage
$photo = base64_decode($data64);
// création de l'image
$image = imagecreatefromstring($photo);
// lecture de l'image
imagejpeg($image);
?>
Vous pouvez aussi enregistrer l’image plutôt que de l’afficher
<?php
// image encodée
$data64 = "/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2Qtan....";
// décodage
$photo = base64_decode($data64);
// création de l'image
$image = imagecreatefromstring($photo);
// enregistrement de l'image
imagejpeg($image,"images/petitChien.jpg");
?>
Si l’affichage passe par une balise HTML, le script à écrire serait :
// image encodée
$data64 = "/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2Qtan....";
// type MINE de l'image
$fileType = 'image/jpeg';
// chemin d'une image en base 64
$dataUrl = 'data:' . $fileType . ';base64,' . $data64;
//affichage de l'image
echo '<img src="'.$dataUrl.'">';
Réduire le poids d’une image
Lorsque vous enregistrer une image avec les fonctions vue ci-dessus, le poids de l’image ne sera pas réduit. Si cette image est uploader via un formulaire HTML et récupérer par la superglobale $_FILES[], sa taille peut-être non négligeable.
Dans un autre cas de figure, la réduction du poids des images devient nécessaire si vous voulez générer des miniatures pour la création d’une galerie de photos.
La fonction imagecopyresampled() permet de copier, redimensionner, et ré-échantillonner une image.
Cette fonction copie une image dans une autre en procédant à un redimensionnement. Cette fonction prend de nombreux paramètres. Dans l’ordre (les noms des variables correspondent à ceux de l’exemple ci dessous):
- L’image de destination ($imDestination)
- L’image source ($imSource)
- La position sur l’axe horizontal de l’image de destination à partir de laquelle la copie sera placée
- Idem sur l’axe vertical
- La position sur l’axe horizontal dans l’image source (0 si on veut copier l’intégralité de l’image source)
- Idem sur l’axe vertical
- La largeur de la copie dans l’image destination ($newWidth)
- Idem pour la hauteur ()
- La largeur de la partie à copier depuis l’image source ($widthOrig car on veut copier l’intégralité de l’image source)
- Idem avec la hauteur
header('Content-Type: image/jpeg');
// source de l'image
$source = "animals-q-c-200-150-8.jpg";
// taux de reduction
$taux = 0.8;
// récupération des dimension de l'image source
list($widthOrig, $heightOrig) = getimagesize($source);
// Calcul des nouvelles dimmensions
$newWidth = $widthOrig * $taux;
$newHeight = $heightOrig * $taux;
// création d'une image vide
$imDestination=imagecreatetruecolor($newWidth,$newHeight);
// création de l'image à partir de la source
$imSource = imagecreatefromjpeg($source);
// copie de l'image avec redimensionnement
imagecopyresampled ($imDestination,$imSource,0,0,0,0,$newWidth,$newHeight,$widthOrig,$heightOrig);
// Affichage
imagejpeg($imDestination);
Image originale
Image réduite
Si au lieux de travailler sur un taux de compression, vous souhaitez définir une largeur ou une hauteur maximale, vous pouvez utiliser le script qui suit.
header('Content-Type: image/jpeg');
// source de l'image
$source = "animals-q-c-200-150-8.jpg";
// Définition de la largeur et de la hauteur maximale
$newWidth = 180;
$newHeight = 180;
// récupération des dimension de l'image source
list($widthOrig, $heightOrig) = getimagesize($source);
// Cacul des nouvelles dimensions
$ratio_orig = $widthOrig/$heightOrig;
if ($newWidth/$newHeight > $ratio_orig) {
$newWidth = $newHeight*$ratio_orig; // mode portait
} else {
$newHeight = $newWidth/$ratio_orig; // mode paysage
}
// création d'une image vide
$imDestination=imagecreatetruecolor($newWidth,$newHeight);
// création de l'image à partir de la source
$imSource = imagecreatefromjpeg($source);
// copie de l'image avec redimensionnement
imagecopyresampled ($imDestination,$imSource,0,0,0,0,$newWidth,$newHeight,$widthOrig,$heightOrig);
// Affichage
imagejpeg($imDestination);
Retourner les images d’une image
En enregistrant une image qui provient d’un mobile ou d’une tablette, celle-ci risque de s’afficher mais avec une mauvaise orientation, elle peut être couchée ou retournée.
Si vous prenez une photo avec votre mobile en mode portrait, l’image sera enregistré couchée. Si vous photographiez en mode paysage mais pas dans le bons sens, l’image semblera renversée.
La fonction exif_read_data() de PHP permet de lire les en-têtes EXIF des images JPEG et TIFF. Avec cette fonction, vous pouvez lire les données méta générées par les appareils photos numériques. La fonction retourne un tableau associatif où les indexes sont les noms des en-têtes et les valeurs sont les valeurs associées à ces en-têtes.
L’index qui nous intéresse est ‘Orientation’ qui peut prendre plusieur valeur
- 8 : l’image est retournée de 90 degré dans le sens anti horaire
- 3 : l’image est retournée de 180 degré
- 6 : l’image est retournée de 90 degré dans le sens horaire
Pour retourner l’image en tenant compte des informations d’en-têtes EXIF, vous pouvez utiliser la fonction imagerotate() qui prend en paramètre la ressource de l’image et l’angle de rotation.
header('Content-Type: image/jpeg');
// source de l'image
$source = "animals-q-c-200-150-8.jpg";
// taux de reduction
$taux = 0.8;
// récupération des dimension de l'image source
list($widthOrig, $heightOrig) = getimagesize($source);
// Calcul des nouvelles dimmensions
$newWidth = $widthOrig * $taux;
$newHeight = $heightOrig * $taux;
// création d'une image vide
$imDestination=imagecreatetruecolor($newWidth,$newHeight);
// création de l'image à partir de la source
$imSource = imagecreatefromjpeg($source);
// orientation de l'image
$exif = exif_read_data($source);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$imSource = imagerotate($image,90,0);
break;
case 3:
$imSource = imagerotate($image,180,0);
break;
case 6:
$imSource = imagerotate($image,-90,0);
break;
}
}
// copie de l'image avec redimensionnement
imagecopyresampled ($imDestination,$imSource,0,0,0,0,$newWidth,$newHeight,$widthOrig,$heightOrig);
// Affichage
imagejpeg($imDestination);
Libérer les ressources mémoire
PHP charge en mémoire l’image sur laquelle il est en train de travailler. Il est recommandé de libérer la mémoire occupée par l’image temporaire avec la fonction imagedestroy(). Elle prend en paramètre la ressource de l’image.
<?php
//PHP réserve en mémoire de l’espace pour stocker l'image
$source = imagecreatefromjpeg($fichierSource);
//libération de l’espace mémoire
imagedestroy($source) ;
?>