Redimensionner et manipuler des images en PHP (avec exemples)

Dans mon précédent tutoriel, nous avons discuté de la manipulation d'images de base à l'aide de la bibliothèque PHP GD. Dans ce tutoriel, j'ai brièvement présenté la bibliothèque et expliqué comment charger des images à partir d'un fichier ou les créer à partir de zéro en PHP. Après cela, nous avons appris à rogner, faire pivoter, redimensionner et retourner une image à l’aide de GD. J'ai couvert le filtre d'image () fonction pour appliquer différents filtres aux ressources image chargées dans le script. J'ai également mentionné certaines fonctions utiles dans GD, comme imagesx () et imagesy () pour obtenir la largeur et la hauteur de l'image chargée.

À la fin de mon dernier tutoriel GD, vous avez appris à utiliser la bibliothèque pour automatiser des tâches élémentaires telles que le redimensionnement de toutes les images d’un répertoire ou l’application de filtres en niveaux de gris avant d’enregistrer le résultat final. Si vous n'avez jamais utilisé la bibliothèque PHP GD auparavant, je vous suggère de lire cet article d'introduction à GD avant de lire celui-ci..

Dans ce didacticiel, nous allons apprendre de nombreuses autres fonctions utiles dans GD et comment les utiliser pour automatiser davantage nos tâches de manipulation d'images..

Manipulation des images à l'aide d'une matrice de convolution

À l'exception des pixels sur les bords, chaque pixel d'une image est entouré de huit autres pixels. Des effets tels que le flou ou la détection des contours sont calculés pour chaque pixel en fonction de la valeur de ce pixel et des valeurs des pixels environnants. Dans la détection de bord, par exemple, un changement de couleur marqué implique que nous avons atteint le bord d’un objet de l’image. Par exemple, un changement soudain du blanc au brun dans l'image ci-dessous signifiera la limite de la tasse et de la table.

Un moyen simple de spécifier ce type de filtre consiste à utiliser une "matrice de convolution". GD fournit les imageconvolution ($ image, $ matrice, $ div, $ offset) fonction pour appliquer une matrice de convolution 3x3 à une ressource image $ image

le $ matrice paramètre est un tableau de trois tableaux, chacun contenant trois valeurs float-i.e. c'est une matrice 3x3. Le premier élément du premier tableau est multiplié par la valeur de couleur du pixel en haut à gauche. De même, le deuxième élément du premier réseau est multiplié par la valeur de couleur du pixel directement au-dessus du pixel central. La couleur finale du pixel est obtenue en additionnant le résultat de toutes ces multiplications puis en le divisant par $ div pour la normalisation. La normalisation garde généralement la valeur de couleur finale en dessous de 255.

Comme nous l'avons vu, le $ div Le paramètre est utilisé comme diviseur pour que le résultat de la convolution normalise sa valeur. le $ offset Le paramètre, quant à lui, permet de spécifier une valeur de décalage pour toutes les couleurs. Vous verrez comment cela affecte le résultat final dans les exemples ci-dessous..

Exemples de convolution

Voici une liste de différentes matrices de convolution que nous avons appliquées à l'image d'une tasse sur une table..

Flou de boîte

$ box_blur = array ([1, 1, 1], [1, 1, 1], [1, 1, 1]); imageconvolution ($ im_php, $ box_blur, 9, 0);

Le flou de surface fonctionne en calculant la moyenne de chaque pixel avec ses voisins. Nous fixons la valeur du diviseur à 9 car la somme de tous les éléments des trois tableaux est 9.

Netteté 

$ sharpen = array ([0, -1, 0], [-1, 5, -1], [0, -1, 0]); imageconvolution ($ im_php, $ sharpen, 1, 0); 

Sharpen agit en exagérant les différences entre chaque pixel et ses voisins. Cela rend les bords un peu plus clairs. Dans le cas de sharpen, le diviseur est toujours 1 car la somme de tous les éléments des trois tableaux est 1. 

Gaufrer

$ emboss = array ([- 2, -1, 0], [-1, 1, 1], [0, 1, 2]); imageconvolution ($ im_php, $ emboss, 1, 0);

La matrice de gaufrage est similaire à la matrice de netteté, à la différence que les valeurs sont négatives en haut à gauche et positives en bas à droite, ce qui crée l'effet de gaufrage. La somme de tous les éléments dans le cas de la matrice de convolution gaufrée est 1, nous n’avons donc pas à nous soucier de la normalisation ou du décalage de couleur..

Détecter bord

$ edge_detect = array ([- 1, -1, -1], [-1, 8, -1], [-1, -1, -1]); imageconvolution ($ im_php, $ edge_detect, 1, 0); imageconvolution ($ im_php, $ edge_detect, 1, 255); 

La détection des contours est similaire à accentuer, mais l’effet est encore plus fort. De plus, la valeur d'origine de l'image n'a pas plus de poids que ses voisins, ce qui signifie que nous nous soucions uniquement des bords, pas des zones colorées pleines d'origine.. 

Avec la détection de bord, la somme de tous les éléments du tableau est 0. Cela signifie que l'image que nous obtiendrons sera généralement noire, sauf modification nette de la couleur, qui se produit généralement aux bords des objets. L’image la plupart du temps noire peut être changée en blanc en réglant le paramètre offset sur 255.

L'image suivante montre le résultat de toutes ces matrices de convolution.

Fonctions de copie d'image

PHP GD a beaucoup de fonctions pour copier une partie d’une image puis la redimensionner ou la fusionner. Lorsque vous utilisez ces fonctions, il est important de noter que PHP considère le coin supérieur gauche d'une ressource image comme son origine. Un positif X valeur vous mènera à la droite de l'image, et un positif y la valeur vous mènera plus bas.

La plus simple de ces fonctions est imagecopy ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h). Il copiera l'image source sur une image de destination. le $ dst_x et $ dst_y les paramètres déterminent le coin supérieur gauche, où l'image copiée sera collée. le $ src_x, $ src_y, $ src_w, et $ src_h les paramètres déterminent la partie rectangulaire de l'image source, qui sera copiée vers la destination.

Vous pouvez utiliser cette fonction pour rogner des images en créant une image à partir de zéro en utilisant imagecreatetruecolor () et copier le rectangle de recadrage de l’image source dans celle-ci. Vous pouvez également l'utiliser pour ajouter des filigranes sur des images, mais vous devez vous rappeler qu'avec cette méthode, la taille du filigrane ne peut pas être modifiée en fonction de la taille de nos images..

Une solution à ce problème consiste à utiliser le imagecopyresized ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ dst_w, $ dst_h, $ src_w, $ src_h) une fonction. Il accepte tous les paramètres de imagecopy () et deux paramètres supplémentaires pour déterminer la taille de la zone de destination où l'image source sera copiée.

le imagecopyresized () la fonction n’est pas parfaite, car elle n’agrandit pas très bien l’image. Cependant, vous pouvez obtenir un redimensionnement de meilleure qualité en utilisant le imagecopyresampled () fonction, qui accepte tous les mêmes paramètres.

Copier avec transparence

Il existe deux autres fonctions liées à la copie d'images que vous trouverez très utiles: imagecopymerge () et imagecopymergegray ().

La fonction imagecopymerge ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h, $ pct) est similaire à imagecopy (), où le supplément $ pct Ce paramètre détermine la transparence de l'image copiée. Une valeur de 0 signifie qu'il n'y a aucune transparence et une valeur de 100 signifie une transparence complète. Cela vous sera d'une grande aide si vous ne souhaitez pas cacher complètement le contenu de l'image principale derrière votre filigrane..

le imagecopymergegray () Par contre, la fonction utilise le dernier paramètre pour convertir l’image source en niveaux de gris. Si elle est définie sur 0, l'image source perdra toute sa couleur. Si elle est définie sur 100, l'image source ne sera pas affectée.

Exemple de copie d'image

L'exemple suivant utilise le imagecopy () fonction pour transformer la moitié droite d'une image en son négatif. Nous avons déjà discuté d'autres fonctions comme filtre d'image () et imagescale () utilisé dans cet extrait de code du didacticiel précédent.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_inv = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); imagefilter ($ im_php_inv, IMG_FILTER_NEGATE); imagecopy ($ im_php, $ im_php_inv, $ im_width / 2, 0, $ im_width / 2, 0, $ im_width / 2, $ im_height); $ new_name = 'fish-mosaic-half-negate.jpg'; imagejpeg ($ im_php, $ new_name);

Ici, nous créons deux copies de l'image d'origine, dont chacune a été réduite à 800 pixels de large. Après cela, nous utilisons le filtre d'image () fonction pour créer un négatif de la $ img_php_inv ressource image. La moitié droite de cette image négative est ensuite copiée sur l'image d'origine à l'aide du bouton imagecopy () une fonction.

C’était une utilisation très basique du imagecopy () une fonction. Vous pouvez voir les résultats ci-dessous. Vous pouvez également diviser l’image en petites sections ou bandes pour créer des effets d’image plus intéressants. Nous allons utiliser le imagecopymergegray () fonctionne dans l'extrait de code ci-dessous pour créer beaucoup plus de bandes dans l'image originale du poisson.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_bw = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); rayures $ = 200; pour ($ i = 0; $ i < $stripes; $i++)  if($i%2 == 0)  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 0);  else  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 100);   imagefilter($im_php, IMG_FILTER_CONTRAST, -255); imagefilter($im_php, IMG_FILTER_COLORIZE, 250, 0, 0, 100); $new_name = 'fish-mosaic-stripes.jpg'; imagejpeg($im_php, $new_name);

L'exemple de code ci-dessus utilise une stratégie similaire à celle de l'exemple précédent, mais cette fois-ci, nous avons divisé l'image en bandes plus petites, qui sont converties en niveaux de gris ou conservées inchangées en fonction de la valeur de la variable. $ i. Une fois toutes les opérations de fusion effectuées, nous appliquons deux filtres sur l'image pour faire ressortir les bandes..

L'image suivante montre le résultat final de ces deux fonctions en conjonction avec différents filtres d'image.

Incorporation de filigranes ou d'autres informations dans des images

Certaines organisations ajoutent des filigranes à leurs images afin d'indiquer clairement qu'elles sont propriétaires de l'image. Cela contribue également à la reconnaissance de la marque et décourage les autres de copier de manière flagrante les images. Grâce à PHP GD, le filigrane des images est une tâche simple..

$ im_php = imagecreatefromjpeg ('waterfall.jpg'); $ watermark = imagecreatefrompng ('watermark.png'); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); $ watermark = imagescale ($ watermark, $ im_width / 5); $ wt_width = imagesx ($ filigrane); $ wt_height = imagesy ($ filigrane); imagecopy ($ im_php, $ filigrane, 0.95 * $ im_width - $ wt_width, 0.95 * $ im_height - $ wt_height, 0, 0, $ wt_width, $ wt_height); $ new_name = 'waterfall-watermark.jpg'; imagejpeg ($ im_php, $ new_name);

Dans l'extrait de code ci-dessus, nous avons créé deux ressources d'image différentes à l'aide de imagecreatefromjpeg () pour l'image principale et imagecreatefrompng () pour le filigrane respectivement. Nous déterminons la largeur et la hauteur de l'image principale à l'aide du imagesx () et imagesy () les fonctions.

Toutes les images que vous souhaitez filigraner n'auront pas les mêmes dimensions. Si vous ne redimensionnez pas le filigrane en fonction des dimensions de l'image principale, le résultat pourrait être étrange. Par exemple, un filigrane à 200 pixels peut s’avérer intéressant sur une image de 1 000 pixels, mais il sera trop grand pour une image de 600 pixels et trop petit pour une image de 2400 pixels.

Par conséquent, nous utilisons le imagescale () permet de toujours garder le filigrane à un cinquième de la largeur de l’image originale. Nous utilisons ensuite le imagecopy () fonction pour placer le filigrane au bon endroit. Voici le résultat final de l'extrait de code ci-dessus.

Outre les filigranes, vous pouvez également ajouter d'autres informations, telles que le lieu où une photo a été prise ou l'heure à laquelle une photo a été prise..

Dernières pensées

Après avoir couvert les bases de la manipulation d’images dans notre précédent tutoriel, nous avons découvert quelques autres fonctions utiles dans la bibliothèque GD. La première partie de ce didacticiel explique comment manipuler des images en PHP avec la matrice de convolution. J'ai également montré quelques exemples d'utilisation de la matrice de convolution pour vous aider à comprendre comment PHP parvient aux valeurs de couleur de différents pixels..

La deuxième partie du didacticiel explique comment copier et / ou redimensionner une partie d’une image pour la coller ailleurs. C'est pratique quand on veut ajouter quelque chose à une image comme un filigrane ou un horodatage.

Essayez d’utiliser toutes ces fonctions pour créer des effets d’image intéressants!