Combina imágenes remotas con cURL e ImageMagick
Usa cURL para descargar un fondo y una superposición, y luego ImageMagick para redimensionarlos y guardar un único JPEG. El script de Bash que aparece a continuación comprueba ambas transferencias HTTPS y elimina sus archivos parciales si falla una descarga o una etapa de procesamiento de imágenes.
Comprueba las herramientas
Esta receta se probó en Linux con Bash 5.3.15, cURL 8.22.0 e ImageMagick 7.1.2-31 con soporte para JPEG
y PNG. Estas son las versiones probadas, no versiones de parche obligatorias. Usa versiones con
mantenimiento activo de cURL e
ImageMagick 7. La versión de cURL debe ser al menos la 8.4: las anteriores
no pueden aplicar el límite de --max-filesize
cuando se desconoce el tamaño de la respuesta.
Comprueba bash --version, curl --disable --version y magick -version antes de guardar el script.
Usa imágenes RGB de un solo fotograma con un fondo opaco; la superposición PNG puede tener
transparencia. El ejemplo usa una foto JPEG y un logotipo PNG de la NASA. Sigue las
directrices de la NASA para el uso de imágenes y medios,
incluidas sus restricciones sobre la insignia y el respaldo institucional.
Guarda el script de composición
Cada fuente se descarga en un directorio privado nuevo. Pasar <(curl ...)
directamente a ImageMagick dificultaría comprobar el estado de salida de la transferencia del fondo.
Guardar y comprobar las entradas reales también evita probar una URL con una solicitud y procesar
una segunda respuesta sin comprobarla.
Guarda este script como compose.sh. Recibe dos URL HTTPS de confianza y un
nuevo directorio de salida cuyo directorio padre ya existe:
#!/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"
Ejecuta el ejemplo
Ejecuta el script guardado desde el directorio que contiene 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
Abre nasa-composite/result.jpg: debería mostrar la foto del alunizaje con el logotipo de la NASA
en la esquina inferior derecha. El rectángulo blanco del logotipo forma parte del PNG original.
El fondo cabe dentro de 1600 × 1600 píxeles y la superposición dentro de 300 × 300, conservando sus
relaciones de aspecto. El > entre comillas en cada
geometría de redimensionamiento impide la ampliación.
-gravity southeast -geometry +20+20 sitúa el lienzo de la superposición a 20 píxeles de los bordes derecho
e inferior. Si sustituyes las imágenes por otras más pequeñas, deja espacio suficiente para la
superposición y ambos márgenes; el script no reduce una superposición demasiado grande para que
quepa en el fondo.
Una tarea completada correctamente imprime Composite saved: seguido de la ruta
absoluta y deja únicamente result.jpg en el nuevo directorio. Ejecutar el script
otra vez con el mismo directorio falla antes de descargar nada y conserva el resultado anterior.
Evita que otros procesos accedan al directorio de la tarea mientras se ejecuta el script.
Gestiona los fallos y reintentos
Los errores HTTP, las transferencias que superan los 10 MiB por fuente y las imágenes que no pueden decodificarse producen un estado de salida distinto de cero y eliminan el nuevo directorio de la tarea. Corrige la URL o la entrada y vuelve a intentarlo con el mismo nombre de directorio. Un directorio existente o la ausencia del directorio padre constituyen un fallo de configuración; el script no modifica el almacenamiento existente.
Una transferencia abortada puede escribir brevemente más datos de los permitidos por el límite; la limpieza elimina ese archivo temporal.
ImageMagick puede recuperar píxeles de un JPEG dañado mientras emite advertencias y devuelve un estado de éxito. Aquí, cualquier diagnóstico escrito en stderr también hace fallar la tarea, imprime el diagnóstico y activa la limpieza. Esto rechaza deliberadamente tanto las advertencias como los errores. No puede detectar daños que un decodificador acepte sin avisar, así que revisa la imagen terminada antes de publicarla.
La función auxiliar de descarga permite tres redirecciones HTTPS y dos reintentos para los fallos que cURL considera reintentables. Cada intento tiene un tiempo límite de 30 segundos. Su ventana de reintentos de 60 segundos determina si se inicia otro intento; un intento que ya esté en curso puede terminar después de esa ventana.
Establece límites para las entradas de confianza
Un archivo comprimido pequeño puede decodificarse como una imagen de gran tamaño. El script limita las dimensiones de entrada y los recursos de la caché de píxeles de ImageMagick, que puede extenderse al disco. Estos ajustes no limitan la memoria total del proceso ni el tiempo de procesamiento. Usa la política de seguridad de ImageMagick y los límites del sistema operativo al ejecutar procesos de trabajo en producción.
Las solicitudes exclusivamente HTTPS siguen permitiendo URL y redirecciones a servicios de redes
privadas. Usa fuentes de confianza; un servicio público sin restricciones que descarga contenido
desde URL necesita controles de red y de origen independientes. Mantén habilitada la verificación
TLS. --disable, colocado primero, impide que cURL cargue un archivo de
configuración predeterminado que podría cambiar estas opciones de descarga.
Para flujos de trabajo gestionados de redimensionamiento y composición, explora el servicio de procesamiento de imágenes de Transloadit.
