Redimensionnement selon le contenu avec PHP et ImageMagick
Utilisez Imagick::liquidRescaleImage() pour modifier les proportions d’une image sans étirer
uniformément chaque objet. Ce guide produit un JPEG de 400 × 300 à partir d’une image locale en PHP.
Le seam carving peut supprimer l’espace vide autour d’un sujet, mais aussi déformer le sujet lui-même.
Qu’est-ce que le redimensionnement selon le contenu ?
Le redimensionnement selon le contenu, ou seam carving, supprime ou insère des chemins de pixels connectés appelés seams. Il privilégie les chemins présentant moins de variations visuelles. Un objet texturé sur un fond uni peut conserver sa forme tandis que le fond rétrécit ; à l’inverse, un visage lisse sur un fond chargé peut être déformé. L’algorithme ne reconnaît pas l’objet qui compte pour vous.
Prérequis
La configuration ci-dessous cible Debian 13 avec PHP 8.4, Imagick 3.8 et ImageMagick 7. Les versions testées étaient PHP 8.4.26, Imagick 3.8.0, ImageMagick 7.1.1-43 et liblqr 0.4.2. Utilisez les mises à jour maintenues par la distribution pour ces branches de versions ; les numéros de correctif indiquent la configuration testée, pas un minimum intrinsèque. PHP 8.4 est pris en charge.
En tant que root sur Debian 13, installez les paquets de l’interface en ligne de commande et de l’extension :
apt-get update &&
apt-get install -y --no-install-recommends php8.4-cli php8.4-imagick imagemagick liblqr-1-0
Debian fournit php8.4-imagick.
Les exemples utilisent un JPEG RGB de confiance, intact et composé d’une seule image, nommé
input.jpg, dans un répertoire de travail accessible en écriture. Conservez
l’original. La validation des téléversements, l’animation et la conversion des profils colorimétriques
sortent du cadre de cet exemple local en ligne de commande.
Prérequis supplémentaires
Installer liblqr seul ne suffit pas : la bibliothèque ImageMagick liée à l’extension Imagick de PHP doit avoir été compilée avec liblqr. Avant d’enregistrer les scripts, testez l’opération directement avec PHP :
php -r '
$im = new Imagick();
$im->newImage(16, 16, "white");
$im->liquidRescaleImage(12, 16, 1, 0);
echo "Liquid rescale available\n";
'
Poursuivez uniquement si cette commande se termine avec succès et affiche
Liquid rescale available. Une extension ou un délégué manquant provoque un échec avant ce
message. Si l’installation ou cette vérification échoue, corrigez le prérequis et répétez cette
étape ; aucun fichier de sortie de cet article n’a encore été créé.
Comment utiliser le redimensionnement liquide en PHP
Enregistrez ce script sous resize.php, à côté de
input.jpg. Les deux dimensions cibles sont en pixels ; adaptez-les au résultat
souhaité.
<?php
$image = new Imagick();
try {
$image->readImage('input.jpg');
$targetWidth = 400;
$targetHeight = 300;
$deltaX = 1; // Maximum sideways step of a seam
$rigidity = 0; // Penalty for bending a seam
$image->liquidRescaleImage($targetWidth, $targetHeight, $deltaX, $rigidity);
$image->writeImage('output.jpg');
printf("Saved output.jpg (%d x %d)\n", $image->getImageWidth(), $image->getImageHeight());
} catch (ImagickException $e) {
fwrite(STDERR, "Image resizing failed.\n");
$failed = true;
} finally {
$image->clear();
}
if (isset($failed)) {
exit(1);
}
Exécutez-le depuis ce répertoire :
php resize.php
Une exécution réussie affiche Saved output.jpg (400 x 300) et enregistre un JPEG de 400 × 300.
Ouvrez-le à côté de l’original : ses dimensions confirment la taille cible, mais pas la préservation
du sujet. Les exécutions réussies remplacent output.jpg. En cas de
ImagickException, le script se termine avec le code de sortie 1 et peut laisser un
ancien fichier de sortie en place ; vérifiez donc le code de sortie avant d’utiliser le fichier.
Ajustement des paramètres
L’opération de redimensionnement liquide est contrôlée par deux paramètres clés :
- deltaX : Déplacement latéral maximal d’un chemin. Zéro produit des chemins droits ; des valeurs plus élevées leur donnent davantage de liberté pour contourner le contenu de l’image.
- rigidity : Pénalité non négative appliquée à la courbure des chemins. Zéro n’ajoute aucune pénalité ; des valeurs plus élevées favorisent des chemins plus droits. Cela ne garantit pas la préservation d’un visage ou d’un autre élément important.
Ces définitions proviennent de la documentation des paramètres d’Imagick. Examinez le résultat sur des images représentatives lorsque vous choisissez les valeurs.
Considérations sur les performances
Pour un original de grande taille, vous pouvez d’abord effectuer un redimensionnement classique
pour réduire le nombre de pixels soumis au seam carving. Enregistrez cette version distincte sous
resize-small.php. Elle ramène les images trop grandes dans les limites de 800 × 600
en conservant leurs proportions, puis applique le seam carving pour obtenir 400 × 300. Elle omet
le redimensionnement initial pour les images plus petites ; sans cette condition,
bestfit: true peut les agrandir, comme l’indique la
documentation de resizeImage.
<?php
$image = new Imagick();
try {
$image->readImage('input.jpg');
if ($image->getImageWidth() > 800 || $image->getImageHeight() > 600) {
$image->resizeImage(800, 600, Imagick::FILTER_LANCZOS, 1, true);
}
$image->liquidRescaleImage(400, 300, 1, 0);
$image->writeImage('optimized-output.jpg');
printf("Saved optimized-output.jpg (%d x %d)\n", $image->getImageWidth(), $image->getImageHeight());
} catch (ImagickException $e) {
fwrite(STDERR, "Image resizing failed.\n");
$failed = true;
} finally {
$image->clear();
}
if (isset($failed)) {
exit(1);
}
php resize-small.php
Ce script affiche Saved optimized-output.jpg (400 x 300) en cas de succès, avec le même comportement de
remplacement et d’échec que le premier script. Le redimensionnement initial réduit aussi le sujet ;
les deux résultats peuvent donc différer visuellement. Si l’image redimensionnée est plus étroite
que 400 pixels ou moins haute que 300, l’opération finale agrandit cette dimension. Comparez
les résultats avant de choisir ce compromis ; il ne garantit ni un traitement plus rapide ni une
meilleure qualité.
Problèmes courants et solutions
Erreurs d’allocation mémoire
Le paramètre memory_limit de PHP ne limite pas de manière fiable les allocations
natives d’ImageMagick. Configurez les
limites de ressources et la politique de sécurité d’ImageMagick,
notamment la mémoire, le cache disque, les dimensions et le temps de traitement, selon votre charge
de travail. Signalez les échecs dus aux limites de ressources plutôt que de réessayer indéfiniment
avec la même image trop grande.
Absence de prise en charge de liblqr
Vérifiez la version liée à l’extension avec :
php --ri imagick
L’interface en ligne de commande autonome d’ImageMagick peut utiliser une autre compilation. Un
délégué répertorié par magick ou par
convert d’ImageMagick 6 ne prouve pas que PHP peut l’utiliser. Répétez
l’opération PHP de la section « Prérequis supplémentaires » après avoir installé une compilation
compatible. Redémarrez tous les processus de travail PHP de longue durée qui utilisent l’ancienne
bibliothèque. Les scripts enregistrés signalent Image resizing failed. et se terminent
avec le code de sortie 1 lorsque l’appel de redimensionnement liquide échoue.
Préservation de la qualité
Le décodage JPEG peut récupérer une partie d’un fichier endommagé et produire malgré tout un résultat. Ces scripts ne vérifient pas l’intégrité de l’entrée ; utilisez un original intact et examinez le résultat entier, y compris son bord inférieur.
Examinez les visages, les inscriptions, les contours droits et les motifs répétés. Les exemples de seam carving d’ImageMagick expliquent pourquoi les fonds chargés peuvent conduire l’algorithme à supprimer des pixels du premier plan. Ni une rigidité accrue ni un renforcement de la netteté ne protègent un sujet particulier. Pour les photos où la forme compte, comparez avec un redimensionnement proportionnel ou un recadrage explicite, puis choisissez le résultat qui conserve le contenu dont vous avez besoin.
Pour conclure
Essayez le script sur quelques images représentatives de votre charge de travail avant de l’appliquer à un lot. Pour le redimensionnement d’images et la conversion de formats via un service hébergé, découvrez l’API de traitement d’images de Transloadit.
