Composer des images distantes avec cURL et ImageMagick
Utilisez cURL pour télécharger une image de fond et une image à superposer, puis ImageMagick pour les redimensionner et enregistrer un seul JPEG. Le script Bash ci-dessous vérifie les deux transferts HTTPS et supprime ses fichiers partiels si un téléchargement ou une étape de traitement d’images échoue.
Vérifier les outils
Cette procédure a été testée sous Linux avec Bash 5.3.15, cURL 8.22.0 et ImageMagick 7.1.2-31 prenant
en charge JPEG et PNG. Ces versions ont été testées, mais ces versions correctives précises ne sont
pas requises. Utilisez des versions maintenues de
cURL et d’ImageMagick 7.
La version de cURL doit être au moins 8.4 : les versions antérieures ne peuvent pas faire respecter
--max-filesize lorsque la taille de la réponse est inconnue.
Vérifiez bash --version, curl --disable --version et magick -version avant d’enregistrer le script.
Utilisez des images RGB constituées d’une seule image, avec un fond opaque ; l’image PNG à
superposer peut comporter de la transparence. L’exemple utilise une photo JPEG et un logo PNG de
la NASA. Respectez les
consignes de la NASA sur l’utilisation des images et des médias,
y compris les restrictions relatives à l’insigne et au soutien officiel.
Enregistrer le script de composition
Chaque source est téléchargée dans un nouveau répertoire privé. Transmettre directement
<(curl ...) à ImageMagick compliquerait la vérification du code de sortie du
transfert de l’image de fond. Enregistrer et vérifier les entrées réellement utilisées évite aussi
de tester une URL avec une requête, puis de traiter une seconde réponse non vérifiée.
Enregistrez ce script sous compose.sh. Il reçoit deux URL HTTPS de confiance et
un nouveau répertoire de sortie dont le parent existe déjà :
#!/bin/bash
set -euo pipefail
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <background-https-url> <overlay-https-url> <new-output-directory>" >&2
exit 1
fi
background_url=$1
overlay_url=$2
output_dir=$3
if ! command -v curl >/dev/null || ! command -v magick >/dev/null; then
echo "Install cURL and ImageMagick 7 before running this script" >&2
exit 1
fi
[[ $output_dir = /* ]] || output_dir=$PWD/$output_dir
if ! mkdir -m 700 -- "$output_dir"; then
echo "Use a new output directory" >&2
exit 1
fi
cleanup() {
local status=$?
rm -f -- "$output_dir/background.image" "$output_dir/overlay.image" "$output_dir/magick.log"
if [ "$status" -ne 0 ]; then
rm -f -- "$output_dir/result.jpg"
rmdir -- "$output_dir"
fi
}
trap cleanup EXIT
fetch_image() {
curl --disable --globoff --fail --silent --show-error --location \
--proto '=https' --proto-redir '=https' --max-redirs 3 \
--connect-timeout 10 --max-time 30 --retry 2 --retry-max-time 60 \
--max-filesize 10485760 --output "$2" --url "$1"
}
fetch_image "$background_url" "$output_dir/background.image"
fetch_image "$overlay_url" "$output_dir/overlay.image"
cd -P -- "$output_dir"
output_dir=$PWD
if ! magick -limit memory 256MiB -limit map 512MiB -limit disk 1GiB \
-limit width 10000 -limit height 10000 \
background.image -resize '1600x1600>' \
\( overlay.image -resize '300x300>' \) \
-gravity southeast -geometry +20+20 -composite result.jpg 2>magick.log ||
[ -s magick.log ]; then
cat magick.log >&2
echo "ImageMagick reported a failure or diagnostic" >&2
exit 1
fi
[ -s result.jpg ] || { echo "No image produced" >&2; exit 1; }
echo "Composite saved: $output_dir/result.jpg"
Exécuter l’exemple
Exécutez le script enregistré depuis le répertoire contenant compose.sh :
bash compose.sh \
'https://images-assets.nasa.gov/image/as11-40-5874/as11-40-5874~orig.jpg' \
'https://www.nasa.gov/wp-content/uploads/2023/04/nasa-logo-web-rgb.png' \
nasa-composite
Ouvrez nasa-composite/result.jpg : l’image devrait montrer la photo de l’alunissage avec le logo
de la NASA dans l’angle inférieur droit. Le rectangle blanc du logo fait partie du PNG source.
L’image de fond tient dans 1600 × 1600 pixels et l’image superposée dans 300 × 300, en conservant leurs
proportions. Le > entre guillemets dans chaque
géométrie de redimensionnement empêche l’agrandissement.
-gravity southeast -geometry +20+20 place le canevas de l’image superposée à 20 pixels des bords droit et
inférieur. Si vous utilisez des images plus petites, laissez assez de place pour l’image superposée
et les deux marges ; le script ne réduit pas une image superposée trop grande pour tenir sur le fond.
Une tâche réussie affiche Composite saved: suivi du chemin absolu et ne laisse que
result.jpg dans le nouveau répertoire. Une nouvelle exécution avec le même
répertoire échoue avant tout téléchargement et préserve le résultat précédent. Empêchez les autres
processus d’accéder au répertoire de la tâche pendant l’exécution du script.
Gérer les échecs et les nouvelles tentatives
Les erreurs HTTP, les transferts dépassant 10 MiB par source et les images impossibles à décoder entraînent un code de sortie non nul et la suppression du nouveau répertoire de la tâche. Corrigez l’URL ou l’entrée et réessayez avec le même nom de répertoire. Un répertoire déjà existant ou un parent manquant constitue une erreur de configuration ; le script préserve les données déjà stockées.
Un transfert interrompu peut brièvement écrire plus que la limite ; le nettoyage supprime ce fichier temporaire.
ImageMagick peut récupérer des pixels d’un JPEG endommagé tout en signalant des avertissements et en renvoyant un résultat de réussite. Ici, tout diagnostic écrit sur stderr fait aussi échouer la tâche, affiche le diagnostic et déclenche le nettoyage. Ce comportement rejette délibérément les avertissements comme les erreurs. Il ne peut pas détecter les dommages qu’un décodeur accepte silencieusement ; inspectez donc l’image finale avant de la publier.
La fonction de téléchargement autorise trois redirections HTTPS et deux nouvelles tentatives pour les échecs que cURL permet de retenter. Chaque tentative a un délai maximal de 30 secondes. Sa fenêtre de 60 secondes pour les nouvelles tentatives détermine si une nouvelle tentative peut démarrer ; une tentative déjà en cours peut se terminer après cette fenêtre.
Fixer des limites pour les entrées de confiance
Un petit fichier compressé peut produire une grande image une fois décodé. Le script limite les dimensions des entrées et les ressources du cache de pixels d’ImageMagick, qui peut déborder sur le disque. Ces réglages ne limitent ni la mémoire totale du processus ni le temps de traitement. Utilisez la politique de sécurité d’ImageMagick et les limites du système d’exploitation lorsque vous exécutez des processus de traitement en production.
Même limitées à HTTPS, les requêtes autorisent les URL et les redirections vers des services du
réseau privé. Utilisez des sources de confiance ; un service public de récupération d’URL sans
restriction nécessite des contrôles distincts portant sur le réseau et les origines. Gardez la vérification TLS
activée. --disable, placé en premier, empêche cURL de charger un fichier de
configuration par défaut qui pourrait modifier ces options de téléchargement.
Pour des flux de travail gérés de redimensionnement et de composition, découvrez le service de traitement d’images de Transloadit.
