⚠️ Este es un sitio de traducción no oficial, sin relación con ImageMagick Studio LLC. Para información autorizada, consulte la página original (https://usage.imagemagick.org/layers/index.html).

Ejemplos de ImageMagick -- Capas de Múltiples Imágenes

Prefacio e Índice de los Ejemplos de ImageMagick
Introducción a las capas
Unir imágenes (Append) (-append)

Introducción a las capas de imágenes

Como ya hemos señalado, ImageMagick no trabaja con una sola imagen, sino con una secuencia o lista de imágenes. Esto permite usar IM en dos técnicas de procesamiento de imágenes muy particulares. Por ejemplo, puede pensar en cada imagen de la lista como un único fotograma en el tiempo, de modo que la lista entera pueda considerarse una Animación. Esto se explora en otras páginas de ejemplos de IM. Consulte Fundamentos de la animación. Por otra parte, puede pensar en cada imagen de la secuencia como Capas de un conjunto de transparencias superpuestas a través de las cuales se ve. Es decir, cada imagen representa una pequeña parte de la imagen final. Por ejemplo: la primera capa (la más baja) puede representar una imagen de fondo. Encima de ella puede haber una sombra difusa y translúcida. Luego, la siguiente imagen de capa contiene el objeto que proyecta esa sombra. Sobre esto, una capa con algún texto escrito sobre ese objeto. Es decir, puede tener una secuencia de imágenes o «capas» en la que cada una añade una pieza más a una imagen mucho más compleja. Cada capa de imagen puede moverse, editarse o modificarse de forma completamente independiente de cualquier otra capa, e incluso guardarse en un archivo de múltiples imágenes (como TIFF:, MIFF: o XCF:) o como imágenes separadas, para su procesamiento posterior. Y ese es el sentido de la disposición en capas. Solo cuando se han creado todas las capas de imagen se Aplana, se hace Mosaico o se Fusiona todas las Imágenes en capas en una única imagen final.


Unir imágenes (Append)

Unir (Appending) es probablemente la más simple de las operaciones multiimagen previstas para manejar varias imágenes. Básicamente, junta la secuencia actual de imágenes en memoria formando una columna o una fila, sin huecos. La opción «[-append](https://imagemagick.org/command-line-options/#append)» une verticalmente, mientras que la forma con signo más «[+append](https://imagemagick.org/command-line-options/#append)» une horizontalmente. Por ejemplo, aquí unimos un conjunto de imágenes de letras una junto a otra para formar una palabra vistosa, de manera parecida a como se unen los «glifos» o letras individuales de una «fuente».

  magick font_A.gif font_P.gif font_P.gif font_E.gif font_N.gif \
          font_D.gif font_E.gif font_D.gif +append  append_row.gif

[IM Output]

El ejemplo anterior es similar (de un modo muy básico) a cómo se manejan las fuentes. A diferencia de las fuentes reales, no está limitado a solo dos colores, sino que puede generar alfabetos muy vistosos y coloridos a partir de imágenes de caracteres individuales. Muchas de estas «fuentes de imagen» están disponibles para descargar en la WWW. Un conjunto muy pequeño se encuentra en Anthony's Icon Library, en Fonts for Text and Counters, que es también donde encontré la Blue Bubble Font anterior. Observe también cómo el operador «[+append](https://imagemagick.org/command-line-options/#append)» se realizó como última operación, después de añadir a la secuencia de imágenes actual todas las imágenes que quería unir. Esto es excelente para añadir una etiqueta a una imagen, por ejemplo… |

  magick rose: -background LawnGreen label:Rose \
          -background white  -append append_label.jpg

[IM Output]
Observe que el color «[-background](https://imagemagick.org/command-line-options/#background)» se usó para rellenar cualquier espacio que no quedara cubierto. Por supuesto, si todas las imágenes tienen el mismo ancho, no quedará espacio para este relleno. A partir de IM v6.4.7-1 se puede usar el ajuste «[-gravity](https://imagemagick.org/command-line-options/#gravity)» para especificar cómo deben combinarse las imágenes. Así, en una unión vertical, un ajuste de «Center» centrará la imagen respecto a la imagen resultante final (igual que un ajuste de «North» o «South»). |

  magick rose: -background LawnGreen label:Rose \
          -background white -gravity center -append \
          append_center.jpg

[IM Output]
Naturalmente, cualquier ajuste de gravedad «East» alineará las imágenes por el lado derecho. |

  magick rose: -background LawnGreen label:Rose \
          -background white -gravity east -append \
          append_east.jpg

[IM Output]
Se puede lograr una alineación vertical similar al usar «[+append](https://imagemagick.org/command-line-options/#append)» | _Antes de IM v6.4.7 era mucho más difícil alinear imágenes unidas, y por lo general implicaba usar «[-flop](https://imagemagick.org/command-line-options/#flop)» para la alineación a la derecha. O usar «[-extent](https://imagemagick.org/command-line-options/#extent)» o «[-border](https://imagemagick.org/command-line-options/#border)» para ajustar el ancho de la imagen en uniones centradas.

Por ejemplo, esto funcionará con una versión más antigua 6.3.2 de IM..._ | |

  magick rose: -background SkyBlue label:Rose \
          -background White -gravity center -extent 200x \
          -append -trim +repage   append_center_old.jpg

[IM Output]
También puede usar varias operaciones de unión en el mismo comando sin conflicto ni confusión sobre el resultado de las operaciones (cosa que no ocurría antes de IM v6). |

  magick font_{0,0,6,1,2}.gif +append  dragon_long.gif \
          -background none   -append   append_multi.gif

[IM Output]
Unimos cada fila de imágenes y luego añadimos debajo una imagen más grande. Esto es muy simple y directo. Usando paréntesis, puede unir solo los números después de la imagen más grande. Por ejemplo, aquí se unen todos los números antes de unirlos verticalmente a la imagen del dragón que leímos antes que los números. |

  magick dragon_long.gif  '(' font_{0,0,6,2,9}.gif +append ')' \
          -background none   -append   append_parenthesis.gif

[IM Output]
| Los paréntesis del ejemplo anterior deben ir entre comillas, o escaparse con una barra invertida («\») cuando se usan con un intérprete UNIX; de lo contrario, el intérprete los interpretará como algo completamente distinto.
---|---
| Como solo intervenían dos imágenes, podríamos haber usado simplemente «[+swap](https://imagemagick.org/command-line-options/#swap)» o «[-reverse](https://imagemagick.org/command-line-options/#reverse)» en lugar de paréntesis.
---|---

Unir un arreglo de imágenes

Puede llevar esto más lejos para crear todo un arreglo de imágenes, y construirlo ya sea por filas o por columnas. |

  magick \( font_1.gif font_2.gif font_3.gif +append \) \
          \( font_4.gif font_5.gif font_6.gif +append \) \
          \( font_7.gif font_8.gif font_9.gif +append \) \
          \( -size 32x32 xc:none  font_0.gif +append \) \
          -background none -append   append_array.gif

[IM Output]
Técnicamente, el primer juego de paréntesis no es necesario, ya que aún no se ha leído ninguna imagen, pero hace que todo se vea uniforme y muestra la intención del comando, que es crear un arreglo de imágenes. Consulte también Modo de concatenación de Montage, para una forma alternativa de crear arreglos de imágenes del mismo tamaño. | _El operador «[-append](https://imagemagick.org/command-line-options/#append)» solo unirá las imágenes reales, y no hace uso del tamaño del lienzo virtual (página de imagen) ni del desplazamiento de la imagen. Sin embargo, la información del lienzo virtual parece quedar en un estado extraño, con los tamaños de lienzo sumados y el desplazamiento fijado en algún valor indefinido.

Esto podría considerarse un error y significa que las imágenes de entrada o el resultado deberían tener el lienzo virtual restablecido con «[+repage](https://imagemagick.org/command-line-options/#repage)» antes de guardar, o antes de usar la imagen en operaciones donde esta información pueda volverse importante.

Probablemente esta situación se corrija en alguna ampliación futura de la operación. Por tanto, se aconseja precaución, especialmente al volver a unir imágenes recortadas en mosaico._
---|---

Unir con solapamiento

En el foro de IM, un usuario preguntó por una forma simple de unir imágenes con cierto solapamiento. Se ofrecieron muchas soluciones. Esta fue una de las más simples, con la cantidad de solapamiento indicada en un solo lugar. |

  magick granite: rose: -gravity east -background none \
          \( -clone 1 -chop 30x0 \) \( -clone 0,2 +append \) \
          -delete 0,2 +swap -composite append_overlap.gif

[IM Output]
El ejemplo anterior no necesitó ningún cálculo de posicionamiento de imágenes, que normalmente implica los tamaños de las imágenes y que representaría una solución más general. Consulte Manejo de capas de imagen más abajo. Lo que hizo fue recortar la parte que se solapaba antes de unir el resultado a la primera imagen, produciendo el tamaño final de la imagen. La imagen original se compone luego (con gravedad) encima para generar el solapamiento real. Se puede modificar fácilmente para solapamiento vertical, o incluso para solapamiento de derecha a izquierda con relativa facilidad.

Unión por aplastamiento (Smush)

Otra forma de unir imágenes es mediante el aplastamiento (smushing). El operador «[-smush](https://imagemagick.org/command-line-options/#smush)» funciona de forma muy parecida al operador Append (véase arriba), pero toma como argumento cuánto espacio (o anti-espacio) quiere entre las imágenes. Por ejemplo, usémoslo para hacer el ejemplo anterior de forma más simple. |

  magick granite: rose: -background none -gravity Center \
          +smush -20 smush_overlap.png

[IM Output]
Eso funciona muy bien, aunque no es para lo que realmente está diseñado el operador, y probablemente sea bastante más lento. Lo que smush está pensado para hacer en realidad es acercar entre sí «imágenes con forma» tanto como sea posible. Por ejemplo, aquí genero las letras «A» y «V» y las «aplasto» juntas con el menor espacio posible entre ellas. |

  magick -background none -pointsize 72 \
          -fill red label:A -fill blue label:V \
          +smush 0 smush_append.png

[IM Output]
Observe cómo las dos letras quedaron unidas mucho más cerca de lo que haría append, aprovechando el espacio vacío de la «forma» de las imágenes. El hueco en el ejemplo anterior se debe a los píxeles de borde con suavizado (anti-aliasing) de las dos letras. Eso es lo que «[-smush](https://imagemagick.org/command-line-options/#smush)» está diseñado para hacer, aunque requiere muchos cálculos, por lo que es bastante más lento que Append (véase arriba). El argumento es un desplazamiento para esa posición final, y suele ser un valor positivo para generar un hueco, pero puede ser negativo para crear un solapamiento. |

  magick -background none -pointsize 72 \
          -fill red label:A -fill blue label:V \
          +smush -15 smush_offset.png

[IM Output]
Las imágenes pueden recortarse de formas no documentadas si se usa un valor negativo muy grande.


Composición de múltiples pares de imágenes

La composición es la operación de bajo nivel que se usa para fusionar dos imágenes individuales. Casi todas las técnicas de capas acaban reduciéndose a fusionar imágenes de dos en dos, hasta que solo queda una imagen. Así que empecemos viendo formas de hacer composición de bajo nivel de pares de imágenes.

Usar el comando Composite

El método tradicional de combinar dos imágenes con ImageMagick es mediante el comando «magick composite». Este comando solo puede combinar dos imágenes a la vez, guardando los resultados de cada operación en un archivo. Por supuesto, esto no impide usarlo para apilar varias imágenes, una imagen a la vez… |

  magick -size 100x100 xc:skyblue composite.gif
  magick composite -geometry  +5+10 balloon.gif composite.gif composite.gif
  magick composite -geometry +35+30 medical.gif composite.gif composite.gif
  magick composite -geometry +62+50 present.gif composite.gif composite.gif
  magick composite -geometry +10+55 shading.gif composite.gif composite.gif

[IM Output]
| _Como ImageMagick lee todas las imágenes de entrada ANTES de abrir la imagen de salida, puede escribir el resultado en una de las imágenes de entrada. Esto permite trabajar sobre la misma imagen una y otra vez, como se muestra arriba, sin problemas.

No haga esto con un formato de imagen con pérdidas como «JPEG», ya que los errores del formato son acumulativos y la imagen base se degradará rápidamente._
---|---
También puede redimensionar la imagen superpuesta además de posicionarla usando el ajuste «[-geometry](https://imagemagick.org/command-line-options/#geometry)». |

  magick -size 100x100 xc:skyblue comp_resize.gif
  magick composite -geometry 40x40+5+10  balloon.gif comp_resize.gif comp_resize.gif
  magick composite -geometry      +35+30 medical.gif comp_resize.gif comp_resize.gif
  magick composite -geometry 24x24+62+50 present.gif comp_resize.gif comp_resize.gif
  magick composite -geometry 16x16+10+55 shading.gif comp_resize.gif comp_resize.gif

[IM Output]
El comando «magick composite» también tiene algunas otras ventajas, ya que puede usarse para controlar la forma en que la imagen se dibuja sobre el fondo con la opción «[-compose](https://imagemagick.org/command-line-options/#compose)», y su posición relativa se ve afectada por el ajuste «[-gravity](https://imagemagick.org/command-line-options/#gravity)». También puede aplicar «[-tile](https://imagemagick.org/command-line-options/#tile)» a la superposición para que cubra toda la imagen de fondo, sin necesidad de especificar límites de mosaico. Esto solo está disponible al usar «magick composite». La gran desventaja de este método es que está usando varios comandos, e IM tiene que escribir la imagen de trabajo, ya sea a una tubería o al disco, para que el siguiente comando vuelva a leerla. Para encontrar más ejemplos del uso del comando «magick composite» para superponer imágenes sobre otras imágenes, consulte «Anotar superponiendo imágenes» e «Posicionamiento de imágenes mediante gravedad».

El operador Composite de Convert

El operador «[-composite](https://imagemagick.org/command-line-options/#composite)» está disponible dentro del comando «magick». Para más detalles, consulte Composición de imágenes en IM. Esto le permite hacer lo mismo que lo anterior, pero todo en un solo comando. |

  magick -size 100x100 xc:skyblue \
          balloon.gif  -geometry  +5+10  -composite \
          medical.gif  -geometry +35+30  -composite \
          present.gif  -geometry +62+50  -composite \
          shading.gif  -geometry +10+55  -composite \
          compose.gif

[IM Output]
Esto primero crea una imagen de lienzo de color «skyblue», y luego apila cada una de las imágenes posteriores sobre ese lienzo en las ubicaciones indicadas. Ahora bien, «[-geometry](https://imagemagick.org/command-line-options/#geometry)» es un operador muy especial que no solo fija una posición de superposición para la siguiente operación «[-composite](https://imagemagick.org/command-line-options/#composite)», sino que también «[-resize](https://imagemagick.org/command-line-options/#resize)» la última imagen (y solo la última imagen) de la secuencia de imágenes actual. |

  magick -size 100x100 xc:skyblue \
          balloon.gif  -geometry 40x40+5+10   -composite \
          medical.gif  -geometry      +35+30  -composite \
          present.gif  -geometry 24x24+62+50  -composite \
          shading.gif  -geometry 16x16+10+55  -composite \
          compose_geometry.gif

[IM Output]
Tenga en cuenta que se recomienda evitar este efecto secundario de «redimensionado» de «[-geometry](https://imagemagick.org/command-line-options/#geometry)», aunque sea cómodo. Básicamente, porque es más bien un efecto de retrocompatibilidad y en algunas situaciones puede generar otros efectos. Esta es la recomendación más explícita… |

  magick -size 100x100 xc:skyblue \
          \( balloon.gif -resize 40x40 \) -geometry +5+10   -composite \
          \( medical.gif               \) -geometry +35+30  -composite \
          \( present.gif -resize 24x24 \) -geometry +62+50  -composite \
          \( shading.gif -resize 16x16 \) -geometry +10+55  -composite \
          compose_resize.gif

[IM Output]

Dibujar múltiples imágenes

También usando «magick» puede emplear primitivas de dibujo para superponer imágenes sobre su lienzo de trabajo. |

  magick -size 100x100 xc:skyblue \
          -draw "image over  5,10 0,0 'balloon.gif'" \
          -draw "image over 35,30 0,0 'medical.gif'" \
          -draw "image over 62,50 0,0 'present.gif'" \
          -draw "image over 10,55 0,0 'shading.gif'" \
          drawn.gif

[IM Output]
Por supuesto, también puede especificar un redimensionado para la imagen superpuesta… |

  magick -size 100x100 xc:skyblue \
          -draw "image over  5,10 40,40 'balloon.gif'" \
          -draw "image over 35,30  0,0  'medical.gif'" \
          -draw "image over 62,50 24,24 'present.gif'" \
          -draw "image over 10,55 16,16 'shading.gif'" \
          drawn_resize.gif

[IM Output]
Las imágenes «dibujadas» también pueden rotarse, escalarse y distorsionarse de forma afín durante el proceso de superposición. Aunque eso puede ser complicado de conseguir como quiere. Las imágenes dibujadas se ven afectadas por «[-gravity](https://imagemagick.org/command-line-options/#gravity)», igual que el texto.


Disposición en capas de múltiples imágenes

La verdadera disposición en capas de imágenes requiere métodos para combinar varias imágenes sin necesidad de componer individualmente cada par de imágenes por separado. Aquí es donde brillan los distintos métodos del operador [-layers](https://imagemagick.org/command-line-options/#layers). El orden de las imágenes en capas puede ser importante, así que conviene entender los operadores especiales de secuencia o lista de imágenes. Tenga en cuenta que las «imágenes en capas» son prácticamente idénticas al manejo de «fotogramas animados». Por ello, se recomienda que consulte también Fundamentos de la animación y Modificaciones de animación para conocer técnicas que implican procesar «capas» o «fotogramas» individuales. De hecho, las animaciones a menudo usan el mismo operador [-layers](https://imagemagick.org/command-line-options/#layers) para procesar imágenes.

Aplanar (Flatten) - sobre una imagen de fondo

El operador de lista de imágenes «[-layers](https://imagemagick.org/command-line-options/#layers) **flatten**» (o su atajo «[-flatten](https://imagemagick.org/command-line-options/#flatten)») básicamente «compondrá» cada una de las imágenes dadas sobre un fondo para formar una sola imagen. No obstante, las posiciones de las imágenes se especifican usando su desplazamiento actual de lienzo virtual o página. Por ejemplo, aquí creo un bonito lienzo y especifico cada una de las imágenes que quiero superponer sobre ese lienzo. |

  magick -size 100x100 xc:skyblue \
          -fill dodgerblue -draw 'circle 50,50 15,25' \
          \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -layers flatten  flatten_canvas.gif

[IM Output]
| _A partir de IM v6.3.6-2, el operador «[-flatten](https://imagemagick.org/command-line-options/#flatten)» es solo un alias del método «[-layers](https://imagemagick.org/command-line-options/#layers) 'flatten'».

Por tanto, la opción «[-flatten](https://imagemagick.org/command-line-options/#flatten)» puede considerarse un atajo del método «[-layers](https://imagemagick.org/command-line-options/#layers)» del mismo nombre._
---|---
No necesita crear un lienzo inicial como hicimos arriba; en su lugar, puede dejar que «[-flatten](https://imagemagick.org/command-line-options/#flatten)» cree uno por usted. El color del lienzo será el color «[-background](https://imagemagick.org/command-line-options/#background)» actual, mientras que su tamaño lo define el tamaño del lienzo virtual de la primera imagen. |

  magick \( -page 100x100+5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50        present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers flatten  flatten_page.gif

[IM Output]
| _Aunque el ajuste «[-gravity](https://imagemagick.org/command-line-options/#gravity)» afectará a la ubicación de la imagen definida con ajustes «[-geometry](https://imagemagick.org/command-line-options/#geometry)», no afectará al posicionamiento de la imagen mediante desplazamientos de lienzo virtual fijados con el ajuste «[-page](https://imagemagick.org/command-line-options/#page)». Esto forma parte de la definición de tales desplazamientos. Consulte Desplazamientos de Geometry frente a Page para más detalles.

Si se necesita colocación con «[-gravity](https://imagemagick.org/command-line-options/#gravity)», consulte los métodos de composición multiimagen anteriores, o el método especial de Composición de capas que puede manejar ambos métodos de posicionamiento simultáneamente._
---|---
Si alguna imagen no aparece en el área definida del lienzo virtual, se recortará o se ignorará, según corresponda. Por ejemplo, aquí usamos un tamaño de lienzo más pequeño, lo que hace que las imágenes posteriores no aparezcan completamente en ese lienzo. |

  magick \( -page 75x75+5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -flatten  flatten_bounds.gif

[IM Output]
El uso normal de Flatten es fusionar varias «capas» de imágenes. Es decir, puede ir generando distintas partes de una imagen más grande, normalmente usando paréntesis para limitar los operadores de imagen a la única «capa» que se está generando, y luego aplanar el resultado final en conjunto. Por ejemplo, un uso típico es crear una capa de imagen de sombra, sobre la cual se aplana la imagen original. Por ejemplo… |

  magick balloon.gif \( +clone  -background navy  -shadow 80x3+5+5 \) +swap \
          -background none   -flatten   flatten_shadow.png

[IM Output]
Tenga en cuenta que, como quería la sombra debajo de la imagen original, necesité intercambiar las dos imágenes para colocarlas en el orden correcto. | _Usar Flatten para añadir imágenes de sombra generadas no se recomienda, ya que las imágenes de sombra generadas pueden tener desplazamientos negativos.

La solución recomendada, como se indica en la sección sobre imágenes de sombra, es usar la técnica más avanzada de fusión de capas, que veremos más adelante._
---|---
Como el lienzo virtual consiste solo en un tamaño, la imagen resultante tendrá ese tamaño, pero no tendrá desplazamiento de lienzo virtual; por tanto, no necesita preocuparse por ningún desplazamiento presente en la imagen final. Este uso del lienzo virtual para definir el lienzo sobre el cual superponer la imagen significa que puede usarlo para añadir un borde alrededor de una imagen. Por ejemplo, aquí fijo el tamaño y el desplazamiento virtual de una imagen para «rellenarla» hasta un tamaño específico. |

  magick medical.gif -set page 64x64+20+20 \
          -background SkyBlue   -flatten   flatten_padding.gif

[IM Output]
Por supuesto, hay mejores formas de rellenar una imagen para que IM centre automáticamente la imagen en el área más grande. Curiosamente, exactamente el mismo manejo puede usarse para «recortar» o Crop una imagen a un lienzo virtual más pequeño que la imagen original. En este caso, sin embargo, conviene usar un desplazamiento negativo para posicionar la ubicación del «recorte», ya que está desplazando la imagen y no posicionando la «ventana» de recorte. |

  magick logo:  -repage 100x100-190-60  -flatten  flatten_crop.gif

[IM Output]
Por supuesto, un recorte de viewport también haría esto mejor, sin el procesamiento adicional de generación de lienzo y superposición que también realiza «[-flatten](https://imagemagick.org/command-line-options/#flatten)». Tampoco «expandirá» la imagen en sí para cubrir todo el viewport si la imagen solo estaba parcialmente contenida en esa ventana de visualización. Un mal uso común del operador «[-flatten](https://imagemagick.org/command-line-options/#flatten)» es eliminar la transparencia de una imagen. Es decir, deshacerse de cualquier transparencia que pueda tener una imagen superponiéndola sobre el color de fondo. Sin embargo, esto no funcionará cuando intervienen varias imágenes y, por tanto, ya no se recomienda.

Mosaico (Mosaic) - expansión del lienzo

El operador «[-layers](https://imagemagick.org/command-line-options/#layers) **mosaic**» (o su atajo «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)») es más bien una versión del operador Flatten con lienzo expandible. En lugar de crear un lienzo inicial basado solo en el tamaño de lienzo de la imagen inicial, el operador Mosaic crea un lienzo lo bastante grande para contener todas las imágenes (solo en la dirección positiva). Por ejemplo, aquí ni siquiera fijo un lienzo virtual apropiado; sin embargo, el operador «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» calculará qué tan grande debe ser ese lienzo para contener todas las capas de imagen. |

  magick \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers mosaic  mosaic.gif

[IM Output]
| _A partir de IM v6.3.6-2, el operador «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» es solo un alias de «[-layers](https://imagemagick.org/command-line-options/#layers) 'mosaic'».

Por tanto, la opción «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» puede considerarse un atajo del método «[-layers](https://imagemagick.org/command-line-options/#layers)» del mismo nombre._
---|---
Tenga en cuenta que tanto «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» como «[-flatten](https://imagemagick.org/command-line-options/#flatten)» siguen creando un lienzo que comienza en el «origen» o píxel 0,0. Esto forma parte de la definición del «lienzo virtual» o «página» de una imagen y, por ello, puede estar seguro de que la imagen final de ambos operadores no tendrá desplazamiento virtual, y todo el lienzo quedará completamente definido en términos de datos de píxeles reales. Tenga en cuenta también que «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» solo expandirá el lienzo en las direcciones positivas (los bordes inferior o derecho), ya que los bordes superior e izquierdo están fijados al origen virtual. Eso, por supuesto, significa que «[-mosaic](https://imagemagick.org/command-line-options/#mosaic)» seguirá recortando imágenes con desplazamientos negativos… |

  magick \( -page -5-10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -mosaic  mosaic_clip.gif

[IM Output]

Fusión (Merging) - crear una nueva imagen de capa

El operador «[-layers](https://imagemagick.org/command-line-options/#layers) **merge**» es casi idéntico a los operadores anteriores y se añadió con IM v6.3.6-2. Solo crea una imagen de lienzo lo bastante grande para contener todas las imágenes dadas en sus respectivos desplazamientos. Al igual que Mosaic, también expandirá el lienzo, pero no solo en la dirección positiva, sino también en la negativa. Básicamente significa que no tiene que preocuparse por el recorte, el desplazamiento u otros aspectos al fusionar capas de imagen. Todas las imágenes se fusionarán de forma relativa a la ubicación de las demás. La salida no incluye ni garantiza que el origen forme parte del lienzo expandido. Por ello, la salida de una fusión de capas puede contener un «desplazamiento de capas» que puede ser positivo o negativo. En otras palabras… la fusión de capas fusiona capas de imagen para producir una nueva imagen de capa. Por ello, si no quiere ese desplazamiento al terminar, probablemente querrá incluir un operador «[+repage](https://imagemagick.org/command-line-options/#repage)» antes del guardado final. Por ejemplo, aquí está el mismo conjunto de capas de imagen que hemos usado antes… |

  magick \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers merge  +repage layers_merge.gif

[IM Output]
Como puede ver, la imagen es justo lo bastante grande para contener todas las imágenes que se colocaron unas respecto a otras, mientras descarté el desplazamiento de la imagen resultante respecto al origen del lienzo virtual. Esta preservación de la posición relativa sin recorte ni espacio extra innecesario es lo que hace tan potente a esta variante. Probemos de nuevo dando a una imagen un desplazamiento negativo… |

  magick \( -page -5-10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers merge  +repage layers_merge_2.gif

[IM Output]
Como puede ver, el «balloon» no se recortó, solo se alejó más de los demás para preservar su distancia relativa a ellos. Por supuesto, el operador «[+repage](https://imagemagick.org/command-line-options/#repage)» en los ejemplos anteriores elimina el desplazamiento absoluto del lienzo virtual en la imagen final, preservando solo las colocaciones relativas entre las imágenes. El desplazamiento se eliminó porque los navegadores web a menudo tienen problemas con los desplazamientos de imagen, y especialmente con los desplazamientos negativos, salvo que formen parte de una animación GIF. Pero si no eliminara ese desplazamiento, todas las imágenes permanecerían en su ubicación correcta sobre el lienzo virtual dentro de la imagen de capa única generada, lo que le permitiría seguir procesando y añadiendo más imágenes a la imagen fusionada. Normalmente usaría un color «[-background](https://imagemagick.org/command-line-options/#background)» de «None», para hacer transparentes las áreas no usadas de la imagen fusionada. Cuando se aplica a una sola imagen, la fusión de capas reemplazará cualquier transparencia de la imagen por el color de fondo sólido, pero preservará el tamaño original de la imagen, así como cualquier desplazamiento de esa imagen. No obstante, el tamaño del lienzo virtual de la imagen puede ajustarse para «encajar mejor» con el tamaño y el desplazamiento de esa imagen. El propósito original del operador era permitir a los usuarios fusionar más fácilmente varias imágenes distorsionadas en un todo unificado, sin importar el desplazamiento de cada imagen. Por ejemplo, al alinear fotos para formar un «panorama» más grande. Podría simplemente empezar con una imagen base central no distorsionada (sin desplazamiento), y usar este operador para superponer las demás imágenes alrededor de ese punto de partida (usando desplazamientos negativos o positivos) que se han alineado y distorsionado para coincidir con esa imagen central. Para otros ejemplos del uso de este operador distorsionando imágenes para alinear puntos de control comunes, consulte Cubo fotográfico isométrico 3D y Caja en perspectiva 3D. Otro ejemplo del uso de este operador es generar una simple serie de fotos superpuestas.

La operación "-layers trim-bounds" puede usarse para asegurar que todas
las imágenes obtengan un desplazamiento positivo en un tamaño de lienzo mínimo,
conservando sus posiciones relativas, y sin fusionar realmente las imágenes en
una única imagen final.

Esto le permite luego realizar más procesamiento de las imágenes antes de que
se fusionen realmente, como colocar más imágenes de forma relativa a ese grupo
de imágenes consultando los límites del lienzo virtual resultante.

No obstante, si las imágenes tienen transparencia, probablemente sea buena idea
recortar primero esa transparencia de las imágenes, siendo el uso ideal...

  -alpha set -bordercolor none -border 1x1 -trim -layers trim-bounds

Esto minimiza las capas de imagen incluyendo todas y cada una de las áreas
transparentes de los datos de imagen reales, asegurando a la vez que todo quede
contenido en un lienzo virtual (positivo) válido de tamaño mínimo.

Composición Coalesce - una disposición progresiva en capas

El operador de imagen «[-layers](https://imagemagick.org/command-line-options/#layers) **coalesce**» (o su atajo «[-coalesce](https://imagemagick.org/command-line-options/#coalesce)») está realmente diseñado para convertir animaciones GIF en una secuencia de imágenes. Para ver ejemplos, consulte Coalescencia de animaciones para más detalles. No obstante, está muy estrechamente asociado con «[-flatten](https://imagemagick.org/command-line-options/#flatten)» y tiene efectos muy útiles para imágenes de múltiples capas en este sentido. Por ejemplo, usar Coalesce en una sola imagen hará exactamente el mismo trabajo que usar Flatten con un color «[-background](https://imagemagick.org/command-line-options/#background)» de «None» o «Transparency». Es decir, «rellenará» el lienzo de la imagen con píxeles transparentes. |

  magick \( -page 100x100+5+10 balloon.gif \) -layers coalesce  coalesce_canvas.gif

[IM Output]
Cuando se trabaja con una imagen formada por múltiples capas, Coalesce puede usarse para generar una «disposición progresiva en capas» de la imagen. Pero para hacerlo necesitamos tomar algunas precauciones, para deshabilitar cualquier manejo de «animación GIF» por parte del operador.

   magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
           \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
           -set dispose None  -coalesce  miff:- |\
     montage - -frame 4 -tile x1 -geometry +2+2 \
             -background none -bordercolor none  coalesce_none.gif

[IM Output]

En el ejemplo anterior, «[-set](https://imagemagick.org/command-line-options/#set)» todos los ajustes «[-dispose](https://imagemagick.org/command-line-options/#dispose)» a «[None](anim_basics.html#none)». Esto efectivamente le dice a «[-coalesce](https://imagemagick.org/command-line-options/#coalesce)» que simplemente superponga cada fotograma sobre los resultados de las superposiciones anteriores. El resultado es que la primera imagen es solo un «relleno» del lienzo de las imágenes, con un fondo transparente. La siguiente imagen es la imagen anterior con esa capa superpuesta. Y así sucesivamente. Un aplanado «progresivo» de la secuencia de imágenes. La última imagen de la secuencia será, por tanto, la misma que si hiciera un «[-flatten](https://imagemagick.org/command-line-options/#flatten)» normal con un fondo transparente. Puede obtener un tipo de efecto completamente distinto si hubiera usado un ajuste «[-dispose](https://imagemagick.org/command-line-options/#dispose)» de «[Background](anim_basics.html#background)». En ese caso, «[-coalesce](https://imagemagick.org/command-line-options/#coalesce)» simplemente «rellenará» el lienzo de cada imagen, ¡como si fueran imágenes completamente separadas!

  magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
          -set dispose Background  -coalesce  miff:- |\
    montage - -frame 4 -tile x1 -geometry +2+2 \
            -background none -bordercolor none  coalesce_bgnd.gif

[IM Output]

No obstante, tenga en cuenta que, a diferencia de Flatten, Mosaic o Merge, el operador «[-coalesce](https://imagemagick.org/command-line-options/#coalesce)» no hace uso del ajuste actual de composición alfa «[-compose](https://imagemagick.org/command-line-options/#compose)». Solo usa un método de composición «[Over](compose.html#over)», ya que esto es lo que se requiere para el manejo de animaciones GIF. El uso de distintos métodos «[-compose](https://imagemagick.org/command-line-options/#compose)» con los operadores de capas de imagen más estándar es el tema del siguiente conjunto de ejemplos.

Métodos de composición y capas

Los tres métodos de disposición en capas: Flatten, Mosaic y Merge, harán uso del ajuste «[-compose](https://imagemagick.org/command-line-options/#compose)» para determinar el método de composición usado al superponer cada imagen en secuencia. Por ello, podría pensar en estas funciones como un operador «[-composite](https://imagemagick.org/command-line-options/#composite)» multiimagen con la capacidad de fijar un lienzo «[-background](https://imagemagick.org/command-line-options/#background)» inicial de un color especificado. Sin embargo, usar cualquier cosa que no sea la composición alfa «Over» por defecto requiere pensarlo antes de aplicarlo, o obtendrá resultados inesperados. Quizá también necesite pensar en el efecto del color «[-background](https://imagemagick.org/command-line-options/#background)» que usan estos operadores para generar el lienzo inicial, sobre el cual se compone cada imagen (incluida la primera). Por ejemplo, coloquemos cada imagen sucesiva debajo de las imágenes anteriores usando un «[DstOver](compose.html#dstover)»… |

  magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
          -background none  -compose DstOver  -flatten  flatten_dstover.gif

[IM Output]
Aquí el fondo se fijó como transparente; de lo contrario, solo verá el lienzo de fondo en el resultado, ¡ya que todas las demás imágenes se habrán colocado «debajo» de ese lienzo inicial! Esto sí ofrece una manera de «vaciar» una imagen con un color particular, como se muestra en Lienzos del tamaño de una imagen existente. Aquí hay un ejemplo más práctico. En lugar de apilar las imágenes con el lienzo de fondo primero, lo cual resulta torpe y poco natural en algunas situaciones de procesamiento de imágenes, puede simplemente generar las imágenes de arriba abajo, o en orden de primer plano a fondo. |

  magick rose: -repage +10+10 \
          \( +clone -background black -shadow 60x3+5+5 \) \
          \( granite: -crop 100x80+0+0 +repage \) \
          -background none  -compose DstOver -layers merge layer_dstover.gif

[IM Output]
Cada una de las tres primeras líneas genera una capa de imagen, y la línea final fusiona todas las capas bajo las capas anteriores, invirtiendo así efectivamente el orden.

Como puede ver, el procesamiento de imágenes anterior fue más simple y limpio de lo que normalmente vería con la generación de sombras, simplemente colocando cada imagen debajo en secuencia (con un lienzo inicial transparente)

Por supuesto, podría haber invertido la lista de imágenes con la misma facilidad. |

  magick rose: -repage +10+10 \
          \( +clone -background black -shadow 60x3+5+5 \) \
          \( granite: -crop 100x80+0+0 +repage \) \
          -reverse -layers merge layer_reverse.gif

[IM Output]
Sin embargo, recuerde que esto solo reordena las imágenes existentes y no afecta al «lienzo de fondo inicial» que crean los métodos de capas. Los métodos de composición también pueden usarse para producir algunos efectos interesantes. Por ejemplo, si dibuja tres círculos y luego los superpone usando el método de composición «Xor», obtiene un símbolo inusual y de aspecto complejo, con un esfuerzo mínimo. |

  magick -size 60x60 \
          \( xc:none -fill blue   -draw 'circle 21,39 24,57' \) \
          \( xc:none -fill red    -draw 'circle 39,39 36,57' \) \
          \( xc:none -fill green  -draw 'circle 30,21 30,3'  \) \
          -background none  -compose Xor   -flatten  flatten_xor.png

[IM Output]

Layers Composite - fusionar dos listas de capas

Con IM v6.3.3-7 se añadió el método «[-layers](https://imagemagick.org/command-line-options/#layers)» «**Composite**», que permite componer dos conjuntos de imágenes completamente separados. Para hacerlo en la línea de comandos, se necesita una imagen marcadora especial «[null:](files.html#null)» que defina dónde termina la primera lista destino de imágenes y comienza la lista de imágenes origen superpuesta. Pero esa es la única complicación real de este método. Básicamente, cada imagen de la primera lista se compone contra la imagen correspondiente de la segunda lista, fusionando efectivamente las dos listas. La segunda lista puede posicionarse globalmente respecto a la primera lista, usando un desplazamiento de geometría, igual que puede hacerlo con un operador Composite normal (véase arriba). La gravedad también se aplica usando el tamaño de lienzo de la primera imagen para hacer los cálculos. Además de ese «desplazamiento global», el desplazamiento virtual individual de cada imagen también se preserva, ya que cada par de imágenes se compone en conjunto. También se maneja un caso especial. Si una de las listas de imágenes contiene una sola imagen, esa imagen se compondrá contra todas las imágenes de la otra lista. También en ese caso, los metadatos de imagen (como los tiempos de animación) de la lista más grande son los que se conservarán, aunque no sea el lado destino de la composición.
Este operador de capas se usa más típicamente al componer dos animaciones, que pueden considerarse una especie de lista de imágenes en capas a lo largo del tiempo. Por ello, se ejemplifica mejor en la sección Modificaciones de animación de los ejemplos. Así que consulte Composición alfa multiimagen para más detalles.


Manejo de capas de imagen

Apilar varias imágenes usando los distintos operadores de capas anteriores es una técnica muy versátil. Le permite trabajar con un gran número de imágenes individualmente y, al terminar, combinarlas todas en un único todo unificado. Hasta ahora hemos mostrado varias formas de fusionar (componer o apilar) varias imágenes de muchas maneras distintas. Aquí ofrezco algunos ejemplos más prácticos sobre cómo aprovechar esas técnicas.

Disposición en capas de imágenes en miniatura

También puede usar esta técnica para fusionar varias miniaturas de formas complejas y variadas. Aquí añado un borde suave a las imágenes a medida que las lee y las posiciona; así puede generar una composición de imágenes bastante agradable sobre un lienzo con mosaico.

  magick -page +5+5    holocaust_tn.gif \
          -page +80+50  spiral_stairs_tn.gif \
          -page +40+105 chinese_chess_tn.gif \
          +page \
          -alpha Set -virtual-pixel transparent \
          -channel A -blur 0x10  -level 50,100% +channel \
          \( -size 200x200 tile:tile_fabric.gif -alpha Set \) -insert 0 \
          -background None -flatten  overlap_canvas.jpg

[IM Output]

Posicionamiento calculado de imágenes.

El desplazamiento del lienzo virtual (página) puede fijarse de muchas maneras. Más concretamente, puede «[-set](https://imagemagick.org/command-line-options/#set)» este atributo por imagen, e incluso calcular una ubicación distinta para cada imagen. Por ejemplo, aquí leo un gran conjunto de imágenes (pequeños iconos, todos del mismo tamaño) y los dispongo en círculo.

  magick {balloon,castle,eye,eyeguy,ghost,hand_point,medical}.gif \
          {news,noseguy,paint_brush,pencil,present,recycle}.gif \
          {shading,skull,snowman,storm,terminal,tree}.gif \
          \
          -set page '+%[fx:80*cos((t/n)*2*pi)]+%[fx:80*sin((t/n)*2*pi)]' \
          \
          -background none -layers merge +repage image_circle.png

[IM Output]

La clave del ejemplo anterior es la operación «[-set](https://imagemagick.org/command-line-options/#set) page», que usa el índice de imagen normalizado (la expresión FX «t/n») para crear un valor de 0.0 a casi 1.0 para cada imagen individual. Este valor se mapea luego para posicionar la imagen (por ángulo) en un círculo de 80 píxeles de radio, usando expresiones FX como escape de porcentaje. La posición calculada es la de la esquina superior izquierda de la imagen (no su centro, aunque ese es un ajuste sencillo), que luego se fusiona para generar una nueva imagen. El posicionamiento se hace sin importar si el desplazamiento es positivo o negativo, que es la potencia del operador de fusión de capas. Es decir, generamos una nueva imagen con todas las imágenes tal como están unas respecto a otras. El «[+repage](https://imagemagick.org/command-line-options/#repage)» final elimina el desplazamiento negativo resultante de la imagen de capa fusionada, ya que ya no se necesita y puede causar problemas al ver la imagen resultante. Tenga en cuenta que la primera imagen (la más a la derecha en el resultado) queda apilada debajo de todas las demás. Si quiere que la disposición en capas sea verdaderamente cíclica, de modo que la última imagen quede debajo de esta primera, quizá deba dividir esa primera imagen por la mitad y poner la mitad superior al final de la secuencia, de modo que la mitad superior de la primera imagen quede sobre la última, mientras que la mitad inferior permanezca bajo la segunda imagen. Esta técnica es potente, pero solo puede posicionar imágenes con un desplazamiento entero. Si necesita un posicionamiento subpíxel más exacto de las imágenes, entonces habrá que distorsionar (trasladar) las imágenes a la ubicación subpíxel exacta en lugar de simplemente ajustar su desplazamiento virtual.

Posiciones calculadas de forma incremental

Puede acceder a algunos atributos de imagen de otras imágenes usando expresiones FX, mientras fija el atributo de las imágenes a medida que se procesan. Esto significa que puede fijar la ubicación de cada imagen de forma relativa a la posición calculada de la imagen anterior. Por ejemplo, esto fija la posición de cada imagen a la derecha de la imagen anterior. Es decir, la posición de la imagen anterior más su ancho.

  magick rose: netscape: granite: \
          \
          +repage -set page '+%[fx:u[t-1]page.x+u[t-1].w]+0' \
          \
          -background none -layers merge +repage append_diy.png

[IM Output]

Cada imagen se une a la ubicación de la imagen anterior, consultando esa ubicación y añadiendo el ancho de esa imagen. Esta ubicación anterior se acababa de calcular, de hecho, mientras IM recorría cada imagen fijando el atributo «page» (desplazamiento virtual). El resultado es un equivalente artesanal del operador Append, a partir del cual puede desarrollar sus propias variantes. Debe tener en cuenta que toda la secuencia se desplaza realmente en «u[-1].w» fijado durante el cálculo de la posición de la primera imagen. Este debería ser el ancho de la última imagen de la secuencia de imágenes actual. No obstante, ese desplazamiento global se descarta con el «[+repage](https://imagemagick.org/command-line-options/#repage)» final. Puede usar algún cálculo extra para que ignore este desplazamiento, pero no es necesario en el ejemplo anterior. | _Al usar un índice de imagen como «u[t]», todos los selectores de imagen «u», «v» y «s» referencian la misma imagen, según el «[index]» dado. Por ello, es mejor usar «u» (la primera imagen o imagen cero) como mnemónico de este comportamiento de indexación (y por si esto cambia).

Para más información, consulte FX, el operador de imagen artesanal._
---|---
Aquí hay otro ejemplo. Cada imagen se desplaza de forma relativa a la imagen anterior, usando tanto la posición como el ancho de esa imagen, para calcular una unión con solapamiento.

magick font_[0-9].gif \
        -set page '+%[fx:u[t-1]page.x+u[t-1].w-8]+%[fx:u[t-1]page.y+4]' \
        -background none -layers merge +repage append_offset.gif

[IM Output]

Esta capacidad de acceder a los atributos de otras imágenes también incluye los datos de píxeles de otras imágenes. Eso significa que podría crear una imagen especial donde los valores de color representen las «posiciones mapeadas» de las demás imágenes. Por supuesto, esa imagen de «mapeo» también estaría posicionada y habría que eliminarla antes de realizar la superposición. Qué tan útil es crear imágenes especiales de «posición mapeada» es otra cuestión. Es solo otra posibilidad.

Posicionamiento de imágenes en dos etapas

Puede simplificar su procesamiento de imágenes separándolo en dos pasos. Un paso puede usarse para generar, distorsionar, posicionar y añadir adornos a las imágenes, con un paso final para fusionarlas todas. Por ejemplo, creemos miniaturas tipo Polaroid a partir de las imágenes originales más grandes de Photo Store, procesando cada una individualmente (manteniendo ese aspecto separado y simple).

  center=0   # Posición inicial del centro de la primera imagen.
             # Puede ser CUALQUIER cosa, ya que solo importan los cambios relativos.

  for image in ../img_photos/[a-m]*_orig.jpg
  do

    # Sumar 70 al desplazamiento relativo de la imagen anterior, para cada imagen
    #
    center=`magick xc: -format "%[fx: $center +70 ]" info:`

    # leer la imagen, añadir adornos, y usando relleno/recorte centrado situar el
    # centro de la imagen en la siguiente ubicación (relativa a la anterior).
    #
    magick -size 500x500 "$image" -thumbnail 240x240 \
            -set caption '%t' -bordercolor Lavender -background black \
            -pointsize 12  -density 96x96  +polaroid  -resize 30% \
            -gravity center -background None -extent 100x100 -trim \
            -repage +${center}+0\!    MIFF:-

  done |
    # leer la tubería de imágenes posicionadas y fusionarlas
    magick -background skyblue   MIFF:-  -layers merge +repage \
            -bordercolor skyblue -border 3x3   overlapped_polaroids.jpg

[IM Output]

El script anterior parece complicado, pero en realidad no lo es. Simplemente genera cada miniatura en un bucle, mientras al mismo tiempo rellena el centro (usando Extent) y recorta cada imagen para que el «centro» de la imagen quede en una ubicación conocida del lienzo virtual. En realidad podría calcular esa posición, aunque eso podría requerir archivos temporales, así que es mejor asegurarse de que esté en una ubicación bien conocida para todas las imágenes. La imagen se traslada luego (usando un operador «[-repage](https://imagemagick.org/command-line-options/#repage)» relativo, consulte Desplazamientos de lienzo), de modo que cada imagen generada quede exactamente 60 píxeles a la derecha de la anterior. Es decir, el centro de cada imagen queda separado a una distancia fija, sin importar el tamaño real de la imagen, que podría haber cambiado debido a relaciones de aspecto y rotaciones. El otro gran truco de este script es que, en lugar de guardar cada «capa de imagen» en un archivo temporal, puede simplemente escribir la imagen en una tubería usando el formato de archivo MIFF:. Un método conocido como transmisión de imágenes MIFF. Esto funciona porque el formato de archivo «MIFF:» permite concatenar simplemente varias imágenes en un único flujo de datos, preservando todos los metadatos de las imágenes, como su desplazamiento de lienzo virtual. Esta técnica es un buen punto de partida para muchos otros scripts. Las imágenes pueden generarse o modificarse, y el tamaño y la posición finales pueden calcularse de la forma que quiera. Otro ejemplo es el script «[hsl_named_colors](../static/img/scripts/hsl_named_colors)», que toma la lista de colores con nombre de ImageMagick y los ordena en una tabla de esos colores en el espacio de color HSL. Puede ver su salida en Especificación de color. Otras posibilidades incluyen…

  • Usar cualquier tipo de miniatura (u otros adornos), o simplemente usar directamente una pequeña miniatura sin procesar.
  • Generar las imágenes de modo que la primera quede centrada y las demás se dispongan a izquierda y derecha bajo esa primera imagen, como una pirámide.
  • Posicionar imágenes en arcos, círculos y espirales, colocándolas en coordenadas X e Y específicas unas respecto a otras. Por ejemplo: PhD Circle, Sunset Flower, Fibonacci Spiral.
  • Posicionar imágenes según su color. Por ejemplo: Book Covers.
  • Posicionar imágenes por hora del día o momento de envío. Por ejemplo: Year of Sunsets

Básicamente, tiene total libertad para posicionar las imágenes en el lienzo virtual, y luego puede simplemente dejar que IM determine el tamaño final del lienzo necesario para contener todas las imágenes.

Chinchetas en un mapa

Aquí hay un ejemplo típico de capas, colocando chinchetas de colores en un mapa, en ubicaciones específicas. [IM Output] A la izquierda hay una imagen de «chincheta». El extremo de la chincheta está en la posición +18+41. También tengo una imagen de un mapa de Venecia y quiero poner una chincheta en varios puntos del mapa. Por ejemplo, «Accademia» está situada en la posición de píxel +160+283. Para alinear la chincheta con esa posición, hay que restar la ubicación del extremo de la chincheta de la posición del mapa. Esto produce un desplazamiento de +142+242 para nuestra imagen de «chincheta». Aquí está el resultado, usando imágenes en capas.

  magick map_venice.jpg    -page +142+242 push_pin.png \
          -flatten  map_push_pin.jpg

[IM Output]

Este ejemplo provino de una discusión del foro de IM, Layering Images with Convert. Automaticemos esto aún más. Tenemos un archivo que lista las ubicaciones y colores de cada una de las chinchetas que queremos colocar en el mapa. El nombre de la ubicación en el archivo no se usa y es solo un comentario de referencia sobre la posición de píxel indicada.

[Data File]

Leamos este archivo de texto para crear las «chinchetas» en un bucle.

  pin_x=18  pin_y=41

  cat map_venice_pins.txt |\
    while read x y color location; do

      [ "X$x" = "X#" ] && continue   # omitir comentarios en los datos

      x=$(( x - pin_x ))    # de coordenadas x,y a desplazamientos de la imagen de chincheta
      y=$(( y - pin_y ))

      # de 'color' a ajustes para modular el color (solo el tono)
      # asume un color 'red' puro para la chincheta original
      mod_args=$(
         magick xc:$color -colorspace HSL txt: |
           tr -sc '0-9\012' ' ' |\
             awk 'NR==1 { depth=$3 }
                  NR==2 { hue=$3;
                          print  "100,100,"  100+200*hue/depth
                        }'; )

      # recolorear y posicionar la chincheta
      magick push_pin.png -repage +${x}+${y} -modulate $mod_args miff:-

    done |\
      # leer la tubería de imágenes posicionadas y fusionarlas
      magick map_venice.jpg  MIFF:-  -flatten  map_venice_pins.jpg

[IM Output]

Tenga en cuenta que asume que el color original de la chincheta es rojo (que tiene un tono de 0) y usa el operador Modulate para recolorearla a otros colores, con los cálculos de escalado apropiados. Tenga en cuenta que el argumento de modulate para un cambio de tono sin efecto es 100, ciclando sobre un valor de 200 (una especie de valor pseudoporcentual). FUTURO: distorsionar el mapa en perspectiva, ajustar el tamaño de la chincheta según la «profundidad» en el mapa, calcular el cambio de posición de la chincheta debido a la distorsión, y «clavarla» en el mapa distorsionado. El ejemplo anterior usó un método conocido como transmisión de imágenes MIFF, con cada imagen generada individualmente en un bucle y luego «canalizada» al comando de «capas» para generar la imagen final. El método alternativo (usado comúnmente en scripts PHP) es usar una técnica de «comando generado», que emplea un script de intérprete para generar un comando «magick» largo que se ejecutará. Los scripts de Animaciones de deformación de imágenes usan esta técnica. Ambos métodos evitan la necesidad de generar imágenes temporales.

Capas de sombras

Manejar correctamente los efectos de sombra semitransparentes en un conjunto de imágenes superpuestas es en realidad mucho más difícil de lo que parece. Simplemente superponer fotos con sombras hará que las sombras se apliquen dos veces. Es decir, dos sombras superpuestas se vuelven muy oscuras, cuando en realidad no se superponen del mismo modo que lo hacen las imágenes superpuestas. Las distintas partes de la imagen deberían estar simplemente sombreadas o no sombreadas. Es decir, las sombras deberían aplicarse una sola vez a cualquier parte de la imagen. No debería obtener áreas más oscuras, salvo que tenga dos fuentes de luz separadas, y eso puede complicar aún más las cosas. Tomas Zathurecky < tom @ ksp.sk > asumió el reto de manejar los efectos de sombra en imágenes en capas, y desarrolló una técnica de acumulador de imágenes para abordar el problema. Básicamente, necesitamos añadir cada imagen al fondo de la pila una a una. A medida que añadimos una nueva imagen, la sombra de todas las imágenes anteriores debe oscurecer la nueva imagen, antes de añadirla a la pila. No obstante, solo debe añadirse la sombra que cae sobre la nueva imagen. Las sombras que no caen sobre la nueva imagen deben ignorarse hasta más tarde, cuando caigan sobre alguna otra imagen, o sobre el fondo (si lo hay). Aquí hay un ejemplo… |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( -clone 0   -background black -shadow 70x3+4+7 \
       -clone 1   -background black -compose DstATop -layers merge \
       -trim \) \
    \( -clone 2,0 -background none  -compose Over -layers merge \) \
    -delete 0--2 \
    \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \( -clone 0   -background black -shadow 70x3+4+7 \
       -clone 1   -background black -compose DstATop -layers merge \
       -trim \) \
    \( -clone 2,0 -background none  -compose Over -layers merge \) \
    -delete 0--2 \
    \
    \( +clone -background black -shadow 70x3+4+7 \) +swap \
    -background none -compose Over -layers merge +repage \
    layers_of_shadows.png

[IM Output]
El programa anterior parece complejo, pero en realidad es bastante directo. La primera imagen se usa para iniciar una pila acumulativa de imágenes (índice de imagen #0). Tenga en cuenta que en realidad podríamos haber empezado con un único píxel transparente («-size 1x1 xc:none»), si no quiere usar esa primera imagen para inicializar la pila. Ahora, para añadir una nueva imagen al fondo de la pila de imágenes, aplicamos el mismo conjunto de operaciones, cada vez…

  • Primero, la miniatura se lee en memoria, y se aplican las rotaciones y colocaciones relativas (que pueden ser negativas). También podría aplicar otras operaciones de miniaturado a la imagen en este punto si quiere, aunque para este ejemplo ya se han realizado. La nueva imagen forma el índice de imagen #1.
  • Ahora tomamos la pila anterior de imágenes (#0) y generamos una sombra con el color, desenfoque, desplazamiento y porcentaje de luz ambiental apropiados.
  • Esta sombra se superpone sobre la nueva imagen (#1) de modo que solo se conserve la sombra que cae «[ATop](compose.html#atop)» la nueva imagen. También (opcionalmente) aplicamos una operación Trim al resultado para eliminar cualquier espacio extra añadido por la operación de sombreado, formando la imagen #2.
  • Ahora simplemente añadimos la nueva imagen (#2) a la pila acumulativa de imágenes (#0).
  • y eliminamos todas las imágenes de trabajo anteriores, excepto la última.

Para añadir más imágenes, básicamente solo repetimos el bloque de operaciones anterior. Después de añadir todas las imágenes a la pila, solo es cuestión de hacer una operación de sombreado normal sobre la pila acumulada de imágenes, eliminando cualquier desplazamiento de imagen restante (que muchos navegadores web detestan). Usando Merge puedo manejar automáticamente los desplazamientos virtuales, especialmente los negativos, lo que permite colocar imágenes donde quiera de forma relativa a las colocaciones de imágenes anteriores. También facilita aplicar sombras, que pueden generar imágenes más grandes con desplazamientos negativos correctamente.
Ahora bien, lo anterior maneja correctamente las sombras de imágenes de múltiples capas, pero aunque la sombra está desplazada, ¡en realidad lo está por igual para todas las imágenes! Lo que realmente debería ocurrir es que la sombra se desplace más y también se vuelva más borrosa a medida que cae sobre imágenes cada vez más profundas en la pila. Es decir, una imagen en lo alto debería proyectar una sombra muy borrosa sobre el fondo, comparada con la imagen más baja. Esto es en realidad más difícil de hacer, ya que no solo necesita llevar la cuenta de la pila de imágenes, sino también de cuán «difusa» se ha vuelto la sombra a medida que la pila de imágenes crece. Por tanto, realmente necesita dos acumuladores. La pila de imágenes (como antes) y la acumulación de sombra, a medida que añadimos más imágenes. Por ejemplo, aquí está el mismo conjunto de imágenes pero con sombras que se vuelven más borrosas con la profundidad. |

  magick xc:none xc:none \
    \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( -clone 1 -background black -shadow 70x0+0+0 \
       -clone 0 -background none -compose Over -layers merge \) \
    -delete 0-1 -trim +repage \
    layers_of_deep_shadows.png

[IM Output]
Observe con atención el resultado. El desplazamiento y la borrosidad de la sombra son distintos en diferentes partes de la imagen. Es muy fina entre imágenes de capas adyacentes, pero muy gruesa cuando cae sobre una imagen, o incluso sobre el fondo mucho más abajo. Por supuesto, en este ejemplo el desplazamiento de la sombra es probablemente demasiado grande, pero el resultado parece muy realista, dando una mejor sensación de profundidad a las capas. Observe cómo dividimos la operación de sombra en dos pasos. Al aplicar la sombra acumulada (índice de imagen #1) a la nueva imagen (#2), solo añadimos el porcentaje de luz ambiental, sin ningún desenfoque ni desplazamiento («70x0+0+0» en este caso). La nueva imagen se añade luego a la pila acumulativa de imágenes (#0). Pero después de añadir la sombra de la nueva imagen (#2) directamente a la sombra acumulada (#1), de nuevo sin desenfoque ni desplazamiento, solo entonces desenfocamos y desplazamos TODAS las sombras, para formar la nueva imagen de sombra acumulada. En otras palabras, la imagen de sombra acumulada se vuelve cada vez más borrosa y desplazada a medida que la pila se hace más y más gruesa. Solo la sombra de las imágenes más profundas no ha acumulado tanto el efecto. Este programa esencialmente separa la aplicación de la sombra del acumulador de sombra incremental. Esto le permite controlar cosas como…

  • Sombra realista (como arriba): 70x0+0+0 y 100x2+4+7
  • Sombra constante (como en el ejemplo básico): 70x2+4+7 y 100x0+0+0
  • desenfoque constante, pero desplazamiento acumulativo: 70x2+0+0 y 100x0+4+7
  • desplazamiento constante y progresivo a la vez: 60x0+4+7 y 100x0+1+1
  • efecto acumulativo de luz ambiental: 80x0+0+0 y 95x2+4+7

La mayoría de ellos son probablemente poco realistas, pero pueden verse bien en otras situaciones. Además, fijar el color «-background» antes de la composición «-compose ATOP» le permitirá definir el color de la sombra (en realidad, una luz ambiental coloreada). Incluso puede usar un color distinto para la sombra que finalmente cae sobre la capa de fondo final (el último ajuste «-background black»), o dejarlo fuera por completo para que parezca que las imágenes no están sobre ningún fondo (es decir, flotando en el aire). Es sumamente versátil.
Tomas Zathurecky desarrolló otro método para manejar las sombras de imágenes en capas, tratando una lista de imágenes en capas como un todo. Algo que yo mismo no habría considerado posible. La ventaja de este método es que puede tratar toda una lista de imágenes como un conjunto, en lugar de tener que acumular una imagen a la vez y repetir el mismo bloque de operaciones una y otra vez. Primero, veamos de nuevo el problema más simple de la «sombra constante». |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \
    -layers trim-bounds \
    \
    \( -clone 0--1 -dispose None -coalesce \
       -background black -shadow 70x2+4+7 \
       xc:none +insert null: +insert +insert xc:none \) \
    -layers trim-bounds -compose Atop -layers composite \
    \
    -fuzz 10% -trim \
    -reverse -background none -compose Over -layers merge +repage \
    coalesced_shadows.png

[IM Output]
El primer bloque de operadores solo genera la lista de imágenes en capas. Podría ser un bucle programado por separado, como se mostró antes. La operación comienza con un «-layers trim-bounds», una operación de recorte de límites que expande el lienzo virtual de todas las imágenes para contenerlas todas, y también asegura que todos los desplazamientos sean positivos. Esto se clona luego, se coalesce y se sombrea para crear una lista progresiva de sombras separada. Ahora podemos usar composición de capas para fusionar las sombras y la lista original de imágenes. La complicación aquí es que, antes de fusionar, necesitamos no solo añadir una imagen marcadora especial «null:» para dividir las dos listas, sino también añadir una imagen en blanco especial «xc:none» para desplazar la lista de sombras, de modo que cada imagen de sombra se superponga «[ATop](compose.html#atop)» la siguiente imagen de la lista original. Todo lo que queda es fusionar las imágenes ahora correctamente sombreadas de abajo arriba (orden inverso).
Para manejar «sombras profundas» se requieren cálculos de capas. |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \
    \( -clone 0--1 \
       -set page '+%[fx:page.x-4*t]+%[fx:page.y-7*t]' -layers merge \) \
    -layers trim-bounds +delete \
    \
    \( -clone 0--1 \
       -set page '+%[fx:page.x-4*t]+%[fx:page.y-7*t]' \
            -dispose None -coalesce \
       -set page '+%[fx:page.x+4*t]+%[fx:page.y+7*t]' \
            -background black -shadow 70x2+4+7 \
       xc:none +insert null: +insert +insert xc:none \) \
    -layers trim-bounds -compose Atop -layers composite \
    \
    -fuzz 10% -trim \
    -reverse -background none -compose Over -layers merge +repage \
    coalesced_deep_shadows.png

[IM Output]
Puede ver el mismo conjunto de bloques que se usó antes, pero con cálculos mucho más complicados para fijar el recorte de límites inicial, y más tarde calcular los desplazamientos necesarios para la «lista de sombras progresiva». No obstante, la sombra actualmente no se vuelve más borrosa con la profundidad. | Lo anterior será mucho más simple usando el comando «magick» de IMv7, que le permitiría usar «cálculos fx» directamente como argumento de «-shadow», lo que le permitiría no solo calcular un desplazamiento mayor para la sombra con la profundidad, sino también hacer la sombra más borrosa con la profundidad.
---|---

Posicionamiento de imágenes en perspectiva distorsionada

Alinear imágenes distorsionadas puede ser complicado, y aquí veré cómo alinear tales imágenes para que coincidan en una ubicación muy específica. Aquí tengo dos imágenes que resaltan un punto específico en cada imagen.

[IM Output] [IM Output]

La segunda imagen es 65% semitransparente, lo que le permite ver a través de ella cuando se compone sobre la imagen azul, de modo que pueda comprobar si los puntos marcados se alinean. Los propios puntos de control marcados están en las coordenadas 59,26 (azul) y 35,14 (rojo) respectivamente. Si simplemente está superponiendo las dos imágenes, puede restar los desplazamientos y «componer» las dos imágenes una sobre otra, produciendo un desplazamiento de +24+12. |

  magick align_blue.png align_red.png -geometry +24+12 \
          -composite align_composite.png

[IM Output]
Tenga en cuenta que ¡este desplazamiento podría ser negativo! Y eso es algo que abordaremos en breve. Esto solo funciona porque las coordenadas son coordenadas de píxel enteras. Si las coordenadas coincidentes son ubicaciones subpíxel (como suele ser el caso en un montaje fotográfico), la composición simple no funcionará. Tampoco funcionará bien si interviene algún tipo de distorsión (lo cual también es común en imágenes de la vida real). Y este es el problema que exploraremos.
Al distorsionar la imagen, querrá asegurarse de que los dos píxeles permanezcan alineados. La mejor forma de hacerlo sería usar los puntos que quiere alinear como puntos de control de distorsión. Esto asegurará que se posicionen correctamente. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort SRT '35.5,14.5  1 75  59.5,26.5' \
          \) -flatten  align_rotate.png

[IM Output]
Como distort genera una «imagen de capa» con un «desplazamiento de lienzo», no puede simplemente usar Composite para superponer las imágenes (demasiado de bajo nivel); en su lugar, necesitamos usar un operador Flatten, para que las posicione usando el desplazamiento generado por distort. Observe cómo también añadí un valor de 0.5 a las coordenadas de «píxel». Esto se debe a que los píxeles tienen área, mientras que los puntos matemáticos no; por ello, si quiere alinear el centro de un píxel, necesita añadir 0.5 a la ubicación del «punto» central dentro del píxel. Consulte Coordenadas de imagen frente a coordenadas de píxel para más información. El otro problema con lo anterior era que la imagen superpuesta quedaba «recortada» por la imagen de lienzo de fondo azul, igual que hace el operador Composite. Es decir, la imagen «azul» proporcionó el «viewport de recorte» para el resultado durante la composición. Para evitar esto, usamos en su lugar Layer Merge, que calcula automáticamente un lienzo «viewport» lo bastante grande para contener todas las imágenes que se componen juntas. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort SRT '35.5,14.5  1 75  59.5,26.5' \
          \) -background none -layers merge +repage  align_rotate_merge.png

[IM Output]
Como resultado de la «fusión», la imagen tendrá un desplazamiento «negativo» (para preservar las posiciones de capa de las imágenes). Para mostrar los resultados necesité descartar ese desplazamiento, ya que muchos navegadores no manejan los desplazamientos negativos en las imágenes. Hago esto usando «+repage» antes de guardar la imagen final. Si fuera a hacer más procesamiento (sin mostrar el resultado en la web), conservaría ese desplazamiento (eliminando el «+repage»), de modo que las posiciones de las imágenes permanezcan en su posición correcta y conocida para el procesamiento posterior.
Ahora bien, las mismas técnicas mostradas arriba también se aplicarían si estuviera haciendo una distorsión más compleja como perspectiva. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '35.5,14.5  59.5,26.5
                       0,0 32,4    0,%h 14,36    %w,%h 72,53  ' \
          \) -background none -layers merge +repage  align_perspective.png

[IM Output]
El problema con esta técnica es que se posiciona la distorsión de perspectiva usando un punto de control interno. Es decir, un punto en el interior de la imagen y 3 puntos alrededor del borde. Eso puede dificultar el control de la forma real de la perspectiva, ya que un pequeño movimiento de cualquier punto de control puede hacer que la «esquina libre» se mueva drásticamente. Esta situación puede ser aún peor si está usando una lista grande de «puntos registrados» para obtener un «ajuste de mínimos cuadrados» más exacto al posicionar las imágenes. En ese caso, el punto que le interesa podría no estar cerca de ninguno de los puntos de control «registrados» usados para distorsionar la imagen. La alternativa es simplemente distorsionar la imagen como necesitamos y luego averiguar cómo necesitamos trasladar la imagen resultante para alinear los puntos que nos interesan. Para que esto funcione, necesitaremos saber cómo se movió el «punto de interés» como resultado de la distorsión. Este es un problema real al distorsionar y posicionar imágenes, especialmente imágenes de la vida real. Por ejemplo, aquí distorsiono la imagen usando las cuatro esquinas para producir una forma de distorsión específica (supuestamente deseada), pero no intentaré alinear los puntos de control en este punto, solo aplicar la distorsión… |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '0,0  10,12  0,%h 14,40
                               %w,0 68,6  %w,%h 63,48 ' \
          \) -background none -layers merge +repage  align_persp_shape.png

[IM Output]
Como puede ver, aunque la imagen roja se distorsionó, la posición del punto de control rojo no está cerca del punto de control azul que queremos alinear. No puede simplemente medir estos dos puntos, ya que es improbable que el punto rojo esté en una posición de píxel exacta, sino que tendrá un desplazamiento subpíxel. Primero necesitaremos calcular exactamente dónde está el punto rojo. Para ello, podemos volver a ejecutar la distorsión anterior con el modo verbose habilitado para obtener los coeficientes de mapeo directo de la perspectiva. Estos pueden usarse luego para calcular como se describe en Distorsión por proyección en perspectiva.

  magick align_red.png  -define distort:viewport=1x1  -verbose \
          +distort Perspective '0,0  10,12  0,%h 14,40
                                %w,0 68,6  %w,%h 63,48 ' null:

[IM Text]

Todo lo que queremos son solo los coeficientes calculados que usa la distorsión. Por ello, no necesitamos la imagen de destino, así que simplemente sacamos la salida usando un formato de archivo de imagen «null:». También le decimos a distort que la nueva imagen que está generando es de solo un píxel de tamaño usando un viewport de distort. De ese modo realiza la preparación de la distorsión y el informe verbose, pero luego solo distorsiona un único píxel de «destino», que después se descarta. Esto puede ahorrar mucho tiempo de procesamiento. En realidad, si la distorsión no usara los metadatos de la imagen de origen (necesarios para los escapes de porcentaje «%w» y «%h») como parte de sus cálculos, ni siquiera necesitaríamos la imagen de origen «align_red.png». En ese caso, podríamos haber usado una imagen de un solo píxel «null:» como imagen de entrada también. Tampoco nos interesan realmente los píxeles virtuales, los fondos ni ninguna otra cosa en este paso de recopilación de información, así que no necesitamos preocuparnos por ajustar esas características.
Ahora que podemos obtener la información de distort, necesitamos extraer los 8 coeficientes de perspectiva, de las líneas 3 y 4 de la salida. Estos pueden usarse luego para mapear el punto de control rojo a su nueva posición distorsionada y, a partir de ahí, restarlo del punto de control azul, para obtener la cantidad real de traslación necesaria para alinear la coordenada roja marcada con la coordenada azul.

  bluex=59; bluey=26
  redx=35; redy=14

  magick align_red.png  -verbose \
             +distort Perspective '0,0  10,12  0,%h 14,40
                               %w,0 68,6  %w,%h 63,48 ' null: 2>&1 |\
    tr -d "',"  |\
      awk 'BEGIN   { redx='"$redx"'+0.5;   redy='"$redy"+0.5';
                     bluex='"$bluex"'+0.5; bluey='"$bluey"'+0.5; }
           NR == 3 { sx=$1; ry=$2;  tx=$3; rx=$4; }
           NR == 4 { sy=$1; ty=$2;  px=$3; py=$4; }
           END { div =  redx*px + redy*py + 1.0;
                 dx = ( redx*sx + redy*ry + tx ) / div;
                 dy = ( redx*rx + redy*sy + ty ) / div;
                 printf "red point now at %f,%f\n", dx, dy;
                 printf "translate shape by %+f %+f\n", bluex-dx, bluey-dy; }'

[IM Text]

Lo anterior usó el filtro de texto «tr» para eliminar comillas y comas extra de la salida. Luego usa el programa «awk» para extraer los coeficientes y hacer las operaciones matemáticas de punto flotante necesarias para «mapear directamente» el marcador rojo de modo que coincida con el marcador azul. Tenga en cuenta que de nuevo añadí 0.5 a las «coordenadas de píxel» de los puntos de control para asegurar que sea el centro del píxel lo que se use en los cálculos. Consulte Coordenadas de imagen frente a coordenadas de píxel. Ahora que conocemos la cantidad de traslación necesaria para la imagen distorsionada, tenemos dos formas de añadir esa traslación a la distorsión. Ya sea modificando los coeficientes de la proyección en perspectiva de forma apropiada (no fácil). O podríamos simplemente añadir las cantidades de traslación a cada una de las coordenadas de destino del original (muy fácil). Aquí está el resultado de esto último (añadir traslaciones a las coordenadas de destino)… |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '0,0   31.408223,15.334305
                                   0,%h  35.408223,43.334305
                                   %w,0  89.408223, 9.334305
                                   %w,%h 84.408223,51.334305 ' \
          \) -background none -layers merge +repage  align_persp_move.png

[IM Output]
A la derecha he recortado y escalado el resultado alrededor de los puntos de control para mostrar que están perfectamente alineados. |

  magick align_persp_shape.png -crop 19x19+50+17 +repage \
          -scale 500%   align_persp_shape_mag.png

[IM Output]
Como puede ver, tenemos una alineación perfecta de los dos píxeles, sin ningún desbordamiento subpíxel hacia ningún lado. Incluso la más mínima desalineación se mostraría como un coloreado asimétrico a uno u otro lado del píxel central. Este escalado incluso muestra una ligera diferencia asimétrica entre los lados izquierdo y derecho de la cruz roja debida a la distorsión de perspectiva. Es decir, así de precisa es esta prueba de visualización a nivel de píxel.
Un problema similar pero más simple se aborda en Posicionamiento de texto mediante Distort.


Evaluate-Sequence - métodos directos de fusión multiimagen

Los métodos «[-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence)» están diseñados para fusionar varias imágenes del mismo tamaño de formas muy específicas. En cierto modo, es una mezcla de los operadores Evaluate y Function combinados con las técnicas de composición multiimagen que hemos visto arriba. Muchos de los métodos ofrecidos pueden incluso realizarse usando técnicas normales de composición de capas multiimagen, pero no todos. El operador usa los mismos métodos que «[-evaluate](https://imagemagick.org/command-line-options/#evaluate)», así que puede obtener una lista de ellos usando «-list Evaluate». Aunque algunos de estos (como «Mean» y «Medium») solo son realmente útiles cuando se usan con este operador.

Media (promedio) de varias imágenes

Esencialmente, tanto el antiguo «-evaluate-sequence mean» como el más reciente «[-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) **mean**» crearán un promedio de todas las imágenes proporcionadas. Por ejemplo, aquí hay un promedio de la imagen rose usando todas sus versiones volteadas vertical y horizontalmente. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence mean  average.png

[IM Output]
Promediar cientos de imágenes de la misma escena fija puede usarse para eliminar la mayoría de los efectos transitorios, como personas en movimiento, haciéndolas menos importantes. No obstante, las áreas con muchos efectos transitorios pueden dejar un «desenfoque fantasmal» que puede ser muy difícil de eliminar. Como las secuencias de vídeo son notoriamente ruidosas cuando se observan los fotogramas individuales, puede promediar varios fotogramas consecutivos, pero sin cambios, para producir un resultado mucho más limpio y nítido. Matt Leigh, de la Universidad de Arizona, informa que ha usado esta técnica para mejorar la resolución de imágenes de microscopio. Toma varias imágenes del mismo «objetivo» y luego las promedia todas para aumentar la relación señal/ruido de los resultados. Sugiere que otros también pueden encontrarlo útil para este propósito. Una alternativa para promediar dos imágenes es usar una operación de imagen «composite -blend 50%», que funcionará con dos imágenes de distinto tamaño. Consulte el ejemplo de Mezclar dos imágenes para más detalles. El foro de discusión de IM tuvo una discusión sobre Promediar una secuencia de 10 fotogramas a la vez, para promediar miles de imágenes sin llenar la memoria del ordenador (lo que lo haría muy lento). Relacionada con esto, y con las matemáticas pertinentes, está la discusión No cargar todas las imágenes a la vez. Otra alternativa a usar «mean» es usar el más reciente operador Poly, que puede ponderar cada imagen individualmente.

Valor máx/mín de varias imágenes

Los métodos «Max» y «Min» obtendrán los valores máximos (más claros) y mínimos (más oscuros) de una secuencia de imágenes. De nuevo, son básicamente equivalentes a usar los métodos de composición Lighten y Darken, pero con varias imágenes. Con la selección adecuada del color de lienzo de fondo, podría usar el operador Flatten con el método de composición equivalente. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence max  max.png

[IM Output]
|

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence min  min.png

[IM Output]
ADVERTENCIA: esto no es una selección de píxeles (por intensidad), sino una selección de valores. Eso significa que la imagen de salida podría resultar en los valores individuales de rojo, verde y azul de imágenes distintas, dando lugar a un color nuevo que no se encuentra en ninguna de las imágenes de entrada. Si necesita que los píxeles se seleccionen por su máx/mín por intensidad, consulte el método de composición Lighten por intensidad.

Píxel mediano por intensidad

El «[-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) **Median**» buscará el píxel que tiene la intensidad del píxel central de todas las imágenes dadas. Es decir, para cada posición recoge y ordena la intensidad de píxel de cada una de las imágenes. Luego elegirá el píxel que cae en el medio de la secuencia. También puede usarse como alternativa a simplemente promediar los píxeles de un conjunto de imágenes. Esto podría usarse, por ejemplo, combinando una imagen con dos imágenes «limitadoras», superior e inferior. Como el píxel será la intensidad media, obtendrá o bien el píxel de la imagen original, o bien un píxel de las imágenes «limitadoras». En otras palabras, puede usar esto para «recortar» la intensidad de la imagen original. Extraño pero cierto. Para un número par de imágenes, se seleccionará el píxel del lado más brillante del medio. Por ello, con solo dos imágenes, este operador será equivalente a un «aclarado por intensidad» píxel a píxel. El punto clave es que cada píxel provendrá completamente de una imagen, ordenado por intensidad. El color exacto de cada píxel provendrá completamente de una de las imágenes dadas, por lo que no se generan colores nuevos. Por ejemplo, aquí están los píxeles de intensidad mediana de la imagen rose usando todas sus versiones volteadas vertical y horizontalmente. Observe cómo no es tan suave, pero podría obtener límites nítidos, ya que se basa en las intensidades de los píxeles. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence median  median.png

[IM Output]

Sumar varias imágenes

El método «Add» simplemente sumará, por supuesto, todas las imágenes.

  magick ... -evaluate-sequence add ...

Que es una versión más rápida (más directa) de usar Flatten para componer con Plus todas las imágenes juntas…

  magick ... -background black -compose plus -layers flatten ...

Tenga en cuenta que sumar imágenes de esta forma puede desbordar muy fácilmente el rango cuántico (Quantum Range) de la imagen y, por ello, puede quedar «recortada», salvo que use una versión HDRI de IM. Por eso normalmente se usa en su lugar un promedio o media, ya que esto dividirá todas las imágenes por igual para asegurar que la imagen resultante no quede recortada. Otra alternativa es usar el más reciente operador Poly, que puede ponderar cada imagen individualmente.

Restar varias imágenes

El método «Subtract» resta cada imagen de la primera. O al menos eso es lo que debería hacer. Internamente tiene los argumentos intercambiados y está restando los resultados anteriores de la imagen siguiente. ¡Arrggggg! No obstante, usando una peculiaridad del método de composición Linear Burn puede restar la segunda y posteriores imágenes de la primera. Básicamente, negando todas menos la primera imagen, y fijando un «white» (cero negado) como color de fondo inicial, puede luego usar Flatten para restar todas las imágenes de la primera.

  magick ...  \
         -negate \( -clone 0 -negate \) -swap 0 +delete \
         -compose LinearBurn -background white -flatten \
         ...

Multiplicar/dividir varias imágenes

«Multiply» y «Divide» se aceptan como métodos en «[-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence)», pero generan resultados inesperados y extraños, ya que usan el valor de color real de las imágenes en lugar del valor de color normalizado, igual que hace «[-evaluate](https://imagemagick.org/command-line-options/#evaluate)». Como resultado, la escala de la multiplicación y la división es demasiado grande. Esto podría clasificarse como un error. Mientras tanto, es mejor que use el método «flatten» equivalente para Multiply, que sí funciona como se espera.

  magick ... -background white -compose multiply -layers flatten ...

Poly - fusionar varias imágenes usando un polinomio

Estrechamente relacionado con «[-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence)», y específicamente con el método «mean» (promediado de imágenes), está el operador «[-poly](https://imagemagick.org/command-line-options/#poly)» (añadido en IM v6.8.0-5). A este operador se le da una lista de dos números por cada imagen en memoria: uno para proporcionar un peso multiplicativo a cada imagen, y otro que es un exponente (potencia) para cada imagen. Esto le permite fusionar una lista de imágenes como si cada imagen fuera la variable de entrada de una ecuación polinómica. Los valores de color de cada imagen se tratan como si fueran un valor normalizado de 0 a 1. Con cada par de valores, el color de la imagen (normalizado) se eleva primero al segundo exponente «potencia de», y luego se pondera (multiplica) por el primer número. Si el exponente es «1», entonces el valor simplemente se multiplica por la ponderación dada. No obstante, si el exponente es «0», la ponderación se convierte en el valor final, produciendo una adición de constante de color normalizada (valor de 0.0 a 1.0). Puede proporcionarse una imagen de un solo píxel en la secuencia de imágenes actual, y puede usarse para añadir un color específico, con un valor de color normalizado distinto para cada canal (usando un peso y un exponente = 1.0). O puede proporcionar una imagen «NULL:» (o cualquier otra imagen de relleno) y usar un exponente de 0.0. Esto solo añadirá el factor de ponderación dado como constante. La imagen final se genera a partir de la primera imagen (y su tamaño y demás metadatos), igual que ocurre con el operador artesanal FX. Por ejemplo… |

  magick rose: granite: null: -poly '1,1 2,1 -1.0,0' poly_rose.png

[IM Output]
Esto toma un «rose:» (sin modificar, usando un peso de 1 y potencia de 1), le añade el doble de los valores de color de la imagen «granite:» (peso=2) y, finalmente, resta un valor de 1 usando una imagen «null:», con un exponente de 0 (ignora la entrada de imagen) y un valor de ponderación de -1.0. La imagen resultante es equivalente a…

rose + 2.0*granite - 1.0

o

rose + 2.0*(granite-0.5)

En otras palabras, a la imagen rose se le da una superposición de textura granítica ruidosa (con un sesgo de gris al 50%). Esto es de hecho exactamente como un efecto de iluminación de composición «[Hard_Light](compose.html#hardlight)» muy fuerte, pero con una ponderación muy explícita de la superposición de granito. La diferencia clave de esto frente a otras operaciones multiimagen es la capacidad de ponderar cada imagen individualmente, pero realizando todos los cálculos en una única operación de procesamiento de imágenes sin necesidad de imágenes intermedias adicionales. Esto evita cualquier redondeo cuántico, recorte u otros efectos en los resultados finales, en una versión no HDRI de ImageMagick. (Consulte Efectos cuánticos). Puede usarse, por ejemplo, para realizar un promedio ponderado de grandes cantidades de imágenes, como promediar grupos más pequeños de imágenes y luego promediar esos grupos juntos.