Para girar o rotar una imagen con ImageMagick tenemos el parámetro -rotate que debe ir seguido por los grados de rotación a girar la imagen.
Veamos un ejemplo. Primero, creamos una imagen:
convert -size 250x250 xc:Blue cuadroazul.png
Y una vez que tenemos la imagen, lo podemos rotar:
convert cuadroazul.png -rotate 45 cuadroazul-rotado.png
Al rotar una imagen nos podemos encontrar con dos problemas, pero para ambos problemas hay solución:
que nos podemos encontrar que el color de fondo no nos guste, que se soluciona con -background
que el resultado sea una imagen con un tamaño que nos descuadre el resto de la composición, que se soluciona con -extent
Veamos los dos con ejemplos. Primero, el color de fondo:
convert cuadroazul.png -background Red -rotate 45 cuadroazul-rotado-confondorojo.png
convert cuadroazul.png -background Red -rotate 45 -extent 250x250 cuadroazul-rotado-confondorojo-ajustado.png
convert cuadroazul.png -background Red -rotate 45 -gravity Center -extent 250x250 cuadroazul-rotado-confondorojo-ajustado-centrado.png
convert -size 500x500 xc:GhostWhite -background NavajoWhite -rotate 45 -gravity NorthEast -extent 1000x1000 cuadroblancosobrefondoblanco-imagemagick.png
Uno de los primeros artículos que escribí en Linux Center sobre ImageMagick versaba sobre cómo generar lienzos simples en ImageMagick.
Ahora, después de haber publicado unos cuantos artículos más sobre ImageMagick me parece un buen momento para hacer una recopilación de las distintas formas de hacer un lienzo y cómo aplicarle efectos para poder generar multitud de imágenes distintas como fondo de escritorio, fondos para escribir textos en redes sociales y llamar así más la atención de los destinatarios, imágenes para WhatsAPP / Telegram... y de paso, ver también cómo construir instrucciones complejas en ImageMagick.
Para generar imágenes con ImageMagick el comando a usar es convert, al cual le tenemos que indicar el tamaño de la imagen con -size, el color a usar con xc: y el nombre de la imagen a generar.
La estructura más sencilla para generar una imagen con ImageMagick sería algo así:
convert -size 500x100 xc:Black franjanegra.png
Podríamos combinar en la misma instrucción varias veces el parámetro xc: con atención a que si no añadimos más parámetros, convert generará tantos ficheros como imágenes generadas con xc:
convert -size 500x100 xc:Black xc:Red xc:Blue franjanegra.png
Generará tres ficheros:
franjanegra-0.png
franjanegra-1.png
franjanegra-2.png
Si queremos que esos lienzos formen parte de un único fichero unido verticalmente necesitamos usar el parámetro append. Con -append la unión será vertical y con +append la unión será horzontal.
convert -size 500x100 xc:Black xc:Red xc:Blue -append tresfranjas.png
Como hemos visto hasta aquí, si únicamente utilizamos un -size, todas las piezas medirán lo mismo. Veamos cómo hacer una imagen con piezas de distintos tamaños. Y de paso, veamos cómo concatenar imágenes en formato horizontal (con +append):
convert -size 100x500 xc:Black -size 200x500 xc:Red -size 300x500 xc:Blue +append tresfranjasverticales.png
A los lienzos generados se les puede añadir nuevos parámetros. Por ejemplo -border que añade un borde al lienzo del color indicado con -bordercolor:
convert -size 300x300 xc:Red -bordercolor Black -border 100x100 negroborderojo.png
Los gradientes de color o degradados básicos que se pueden hacer en ImageMagick son lineales o radiales, con los parámetros gradient: y radial-gradient: en lugar de xc:
convert -size 500x500 gradient:Red-Blue degradadorojoazul.png
convert -size 500x500 radial-gradient:Red-Blue degradadoradialrojoazul.png
Una vez visto este recordatorio, aquí empezamos con la elaboración de instrucciones complejas en ImageMagick.
Los degradados lineales realizados con gradient no permiten grandes posibildades de adaptación, pero podemos unir parámetros, como xc: y gradient: para poder hacer imágenes en el que haya partes sin degradados:
convert -size 500x100 xc:Red -size 500x300 gradient:Red-Blue -size 500x100 xc:Blue -append unionxcgradient.png
Vamos a rizar un poco más el rizo y vamos a unir un parámetro más, el parámetro rotate para girar la imagen y que el degradado tenga formato horizontal:
convert -size 500x100 xc:Red -size 500x300 gradient:Red-Blue -size 500x100 xc:Blue -append -rotate 90 unionxcgradientgirado.png
Podemos encadenar distintos gradientes y lienzos lisos, tantos como queramos, aquí uniremos dos degradados con un lienzo liso a modo de ejemplo:
convert -size 500x200 gradient:Red-Blue -size 500x100 xc:Blue -size 500x200 gradient:Blue-Red -append doblegradiente.png
A los lienzos creados, podemos aplicarles un difuminado posterior para que haga el efecto de degradado
convert -size 500x250 xc:Blue xc:Red -append -blur 0x250 difuminadoblur.png
Y aquí viene un punto muy importante que quiero remarcar:
ImageMagick procesa los parámetros de izquierda a derecha, así que para que pueda generarse el difuminado en la unión de los dos lienzos es necesario que el parámetro -append esté antes del parámetro -blur.
A convert se le puede indicar que haga degradados en direcciones concretas. Tanto lineales como radiales. Veamos esta última opción con distintos grados aplicados como valor al parámetro -radial-blur ya que es más sencillo ver el resultado en una imagen que leer su descripción:
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 45 difuminadoradialblur-45.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 90 difuminadoradialblur-90.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 135 difuminadoradialblur-135.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 180 difuminadoradialblur-180.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 225 difuminadoradialblur-225.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 270 difuminadoradialblur-270.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 315 difuminadoradialblur-315.png
convert -size 500x250 xc:Blue xc:Red -append -radial-blur 360 difuminadoradialblur-360.png
Vista la evolución de -radial-blur, veamos lo mismo con -motion-blur, que cuenta con tres parámetros: $radioX$sigma+$ángulo
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+45 difuminadomotionblur-45.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+90 difuminadomotionblur-90.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+135 difuminadomotionblur-135.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+180 difuminadomotionblur-180.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+225 difuminadomotionblur-225.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+270 difuminadomotionblur-270.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+315 difuminadomotionblur-315.png
convert -size 500x250 xc:Blue xc:Red -append -motion-blur 0x100+360 difuminadomotionblur-360.png
Sobre todo quiero que se note cómo afecta a la imagen un -motion-blur con un ángulo de 180 ó 360 grados en una imagen con dos franjas horizontales. Y ahora veamos cómo afecta el valor del ángulo tanto en -radial-blur como -motion-blur en una imagen con predominancia de un color y una forma que la cruce. Por ejemplo, una cruz de San Jorge:
convert -size 400x400 xc:White -background Red -splice 100x100+200+200 sanjorge.png
Y ahora vamos a hacer una evolución de un -motion-blur y un -radial-blur para ver cómo afecta cuando la imagen muestra una forma de cruz:
Veamos la diferencia entre -motion-blur 90 y -motion-blur 180
Y entre -motion-blur 45 y -motion-blur 135
Y en cuanto a -radial-blur, veamos como afecta con 90 y múltiplos de 90: 180, 270 y 360:
Y sin embargo, cómo afecta cuando no son mútliplos de 90:
-radial-blur 45
-radial-blur 135
-radial-blur 225
-radial-blur 315
Otra forma de modificar las imágenes y hacer menos nítidos los bordes es mediantes las dispersiones con el parámetro -spread:
convert -size 500x250 xc:Red xc:Blue -append -spread 5 rojoazul-spread5.png
[code]convert -size 500x250 xc:Red xc:Blue -append -spread 50 rojoazul-spread50.png[/code]
Incluso se puede aplicar un valor mayor al tamaño en píxeles de la altura de la imagen dando un efecto de caos total:
convet -size 500x250 xc:Red xc:Blue -append -spread 1000 rojoazul-spread1000.png
En una imagen en el que no están definidas las líneas, sí que afecta el -motion-blur con 180 y 360:
[code]convert -size 500x250 xc:Red xc:Blue -append -spread 1000 -motion-blur 0x100+180 rojoazul-spread1000-motion-blur180.png[/code]
convert -size 500x250 xc:Red xc:Blue -append -spread 1000 -motion-blur 0x100+360 rojoazul-spread1000-motion-blur360.png
convert -size 500x250 xc:Red xc:Blue -append -spread 1000 -radial-blur 90 rojoazul-spread1000-radial-blur90.png
convert -size 500x250 xc:Red xc:Blue -append -spread 1000 -radial-blur 360 rojoazul-spread1000-radial-blur360.png
convert -size 500x250 xc:Red xc:Blue -append -radial-blur 360 -spread 1000 rojoazul-radial-blur360-spread1000.png
[code]convert -size 500x250 xc:Red xc:Blue -append -radial-blur 360 rojoazul-radial-blur360-sin-spread.png[/code]
En ImageMagick podemos seleccionar colores de varias maneras, principalmente mediante el nombre predefinido del color o mediante un código hexadecimal.
Ya hemos visto en otros artículos que para trabajar con los colores predefinidos por ImageMagick podemos listarlos con:
convert -list color
Y usar esos colores. Es una forma muy útil y práctica de trabajar, pero esto nos limita a unos cuantos colores, unos setecientos según la versión, podemos saber la cantidad con:
convert -list color | wc -l
Y además no nos permite trabajar con transparencias.
Por lo tanto, el trabajo con código hexadecimal, aunque nos obligue a un pequeño mayor esfuerzo a la hora de programar, nos ofrece una mayor cantidad de colores. Con los nombres de los colores predefinidos tenemos algo menos de 700 colores frente a los 255 * 255 * 255 colores con los que podemos trabajar si usamos códigos hexadecimales. Y si usamos el canal alpha para las transparencias, el número pasa a ser de 255 * 255 * 255 * 255 = 4.228,250.625 colores posibles.
Podemos escribir a mano el código:
convert -size 500x200 xc:#11223344 imagen.png
O podemos generar ese código aleatoriamente.
Para ello nos ayudaremos de shuf para generar un número aleatorio y bc para convertir de decimal a hexadecimal.
Y veamos una función que nos genere aleatoriamente un código hexadecimal de color en nuestros scripts. Pero que, además de dar la posibilidad de generar aleatoriamente un color aleatorio que le podamos indicar que tenga una tonalidad rojiza, verdosa o azulada, o bien que tenga menos coloración de uno de esos canales, que el color sea claro u oscuro y que tenga o no transparencia. Para ello uso una serie de parámetros en la función:
t T -t -T -> Se añade un canal Alfa de transparencia
d D -d -D o O -o -O -> oscuro o dark, el color generado será oscuro, entre 0 y 85 (255 / 3)
l L -l -L c C -c -C -> claro o light, el color será claro, entre 170 ( 255 / 3 * 2 ) y 255
gb GB -gb -GB bg BG -bg -BG -> Mayor cantidad de verde y azul que de rojo
rb RB -rb -RB br BR -br -BR -> Mayor cantidad de rojo y azul que de verde
rg RG -rg -RG gr GR -gr -GR -> Mayor cantidad de rojo y verde que de azul
b B -b -B -> Color azulado
g G -g -G -> Color verdoso
r R -r -R -> Color rojizo
Con esas premisas, aquí dejo la función en un script de ejemplo:
#!/bin/bash
function devuelvecolor()
{
if [ $1 = "r" ] || [ $1 = "R" ] || [ $1 = "-r" ] || [ $1 = "-R" ]
then
let decimalrojo=$(shuf -i 128-255 -n 1)
let decimalverde=$(shuf -i 0-127 -n 1)
let decimalazul=$(shuf -i 0-127 -n 1)
elif [ $1 = "g" ] || [ $1 = "G" ] || [ $1 = "-g" ] || [ $1 = "-G" ]
then
let decimalrojo=$(shuf -i 0-127 -n 1)
let decimalverde=$(shuf -i 128-255 -n 1)
let decimalazul=$(shuf -i 0-127 -n 1)
elif [ $1 = "b" ] || [ $1 = "B" ] || [ $1 = "-b" ] || [ $1 = "-B" ]
then
let decimalrojo=$(shuf -i 0-127 -n 1)
let decimalverde=$(shuf -i 0-127 -n 1)
let decimalazul=$(shuf -i 128-255 -n 1)
elif [ $1 = "rg" ] || [ $1 = "RG" ] || [ $1 = "-rg" ] || [ $1 = "-RG" ] || [ $1 = "gr" ] || [ $1 = "GR" ] || [ $1 = "-gr" ] || [ $1 = "-GR" ]
then
let decimalrojo=$(shuf -i 128-255 -n 1)
let decimalverde=$(shuf -i 128-255 -n 1)
let decimalazul=$(shuf -i 0-127 -n 1)
elif [ $1 = "rb" ] || [ $1 = "RB" ] || [ $1 = "-rb" ] || [ $1 = "-RB" ] || [ $1 = "br" ] || [ $1 = "BR" ] || [ $1 = "-br" ] || [ $1 = "-BR" ]
then
let decimalrojo=$(shuf -i 128-255 -n 1)
let decimalverde=$(shuf -i 0-127 -n 1)
let decimalazul=$(shuf -i 128-255 -n 1)
elif [ $1 = "gb" ] || [ $1 = "GB" ] || [ $1 = "-gb" ] || [ $1 = "-GB" ] || [ $1 = "bg" ] || [ $1 = "BG" ] || [ $1 = "-bg" ] || [ $1 = "-BG" ]
then
let decimalrojo=$(shuf -i 0-127 -n 1)
let decimalverde=$(shuf -i 128-255 -n 1)
let decimalazul=$(shuf -i 128-255 -n 1)
elif [ $1 = "l" ] || [ $1 = "L" ] || [ $1 = "-l" ] || [ $1 = "-L" ] || [ $1 = "c" ] || [ $1 = "C" ] || [ $1 = "-c" ] || [ $1 = "-C" ]
then
let decimalrojo=$(shuf -i 170-255 -n 1)
let decimalverde=$(shuf -i 170-255 -n 1)
let decimalazul=$(shuf -i 170-255 -n 1)
elif [ $1 = "d" ] || [ $1 = "D" ] || [ $1 = "-d" ] || [ $1 = "-D" ] || [ $1 = "o" ] || [ $1 = "O" ] || [ $1 = "-o" ] || [ $1 = "-O" ]
then
let decimalrojo=$(shuf -i 0-85 -n 1)
let decimalverde=$(shuf -i 0-85 -n 1)
let decimalazul=$(shuf -i 0-85 -n 1)
else
let decimalrojo=$(shuf -i 0-255 -n 1)
let decimalverde=$(shuf -i 0-100 -n 1)
let decimalazul=$(shuf -i 0-255 -n 1)
fi
if [ "$2" ]
then
if [ $1 = "t" ] || [ $1 = "T" ] || [ $2 = "t" ] || [ $2 = "T" ] || [ $1 = "-t" ] || [ $1 = "-T" ] || [ $2 = "-t" ] || [ $2 = "-T" ]
then
let decimaltransparencia=$(shuf -i 30-125 -n 1)
hexadecimaltransparencia=$(echo "ibase=10;obase=16;$decimaltransparencia" | bc)
if [ `expr length $hexadecimaltransparencia` -lt 2 ]
then
hexadecimaltransparencia="0"$hexadecimaltransparencia
fi
fi
fi
hexadecimalrojo=$(echo "ibase=10;obase=16;$decimalrojo" | bc)
if [ `expr length $hexadecimalrojo` -lt 2 ]
then
hexadecimalrojo="0"$hexadecimalrojo
fi
hexadecimalverde=$(echo "ibase=10;obase=16;$decimalverde" | bc)
if [ `expr length $hexadecimalverde` -lt 2 ]
then
hexadecimalverde="0"$hexadecimalverde
fi
hexadecimalazul=$(echo "ibase=10;obase=16;$decimalazul" | bc)
if [ `expr length $hexadecimalazul` -lt 2 ]
then
hexadecimalazul="0"$hexadecimalazul
fi
echo "#"$hexadecimalrojo$hexadecimalverde$hexadecimalazul$hexadecimaltransparencia
}
devuelvecolor R t
Concatenar vídeos con ffmpeg no da siempre los resultados esperados, depende de la versión, de los codecs instalados y varios factores que pueden hacer que el script que en un equipo funciona perfectamente, en otro ordenador no funcione tan bien.
Lo que nunca falla es ImageMagick -sic-. Así pues, voy a comentar un script que funcionaría, o debería funcionar, en todos los sistemas:
El objetivo es el mismo que el del artículo sobre cómo componer vídeos con fotografías y sonido:
Un script que reciba un fichero de audio como parámetro, por ejemplo un podcast, aunque podría ser cualqueir otro fichero de audio, con una duración variable y que se genere un vídeo con unos elementos básicos para un vídeo de YouTube:
La imagen de la llamada a la acción o las redes sociales podría ser también una animación o una secuencia de vídeo. Su adaptación simplemente sería cambiar la imagen fija por un vídeo y copiar la parte de la entradilla. De hecho, si he combinado vídeo con imagen fija ha sido precisamente para que este script pueda ser germen para otras adaptaciones.
Y, de paso, ver en acción el contenido explicado en otros artículos:
La explicación del código está en estos artículos. El resto, en los comentarios del script:
#!/bin/bash
function numerodesegundos()
{
let horasdeaudio=${1:0:2}
let minutosdeaudio=${1:3:2}
let segundosdeaudio=${1:6:2}
echo $[ ($horasdeaudio*60*60) + ($minutosdeaudio*60) + $segundosdeaudio ]
}
function compruebaentradilla()
{
# Comprueba si la entradilla tiene su directorio
# y están los fotogramas desmontados ahí.
#
# Si no lo está, crea el directorio y
# desmonta los fotogramas de la entradilla
if [ ! -d $directorioentradilla ]
then
mkdir $directorioentradilla
ffmpeg -i $entradilla $directorioentradilla/fotograma%04d.png
else
let contenido=$(ls $directorioentradilla | wc -l)
if [ $contenido -eq 0 ]
then
ffmpeg -i $entradilla $directorioentradilla/fotograma%04d.png
fi
fi
fotogramasentradilla=$(ls $directorioentradilla | wc -l)
echo $fotogramasentradilla
}
# Extrae el nombre del fichero de audio pasado como parámetro quitando la extensión
sinextension=${1%.*}
# Calcula la duración del audio del fichero pasado como argumento
duracion=$(./vinfo.sh duration $1)
# Ficheros auxiliares
entradilla="entradilla.mp4"
directorioentradilla="entradilla"
imagenprincipal="fondopodcast.png"
redessociales="redessociales.png"
pantallafinal="pantallafinal.png"
# Calcula la duración en segundos del audio y el número de fotogramas necesarios para el vídeo
segundosdeaudio=$(numerodesegundos $duracion)
let totalfotogramas=$segundosdeaudio*24
fotogramasentradilla=$(compruebaentradilla)
# Calcula la duración de la entradilla
duracionentradilla=$(./vinfo.sh duration $entradilla)
segundosentradilla=${duracionentradilla:6:2}
# Calcula cuánto duran los contenidos extras con dos cortes para la cartela de redes sociales
let duracionextras=$segundosentradilla+5+5+20
# Calcula la diferencia entre los segundos de audio del fichero parámetro y los extras
let tiempototalarellenar=$segundosdeaudio-$duracionextras
# Como vamos a hacer dos cortes para la cartela de redes sociales, divide el tiempo entre 3
let tercio=$tiempototalarellenar/3
let fotogramastercio=$tercio*24
##############################################################################
#
# Los bloques de imágenes quedarán así:
# Entradilla -> del fotograma 1 hasta que se acaben los fotogramas de la entradilla
# Imagen Principal -> desde último fotograma entradilla + 1 hasta un tercio de los fotogramas restantes más
# Cartela Redes Sociales: 5 segundos x 24 fotogramas = 120 fotogramas
#
# Nuevo bloque de: Imagen principal + cartela redes sociales + imagen principal
# Este bloque hay que repetirlo a mano, con un while que compruebe los bloques
# no funciona el convert imagen.png png:- para pasárselo a ffmpeg
#
# Pantalla final: 20 segundos x 24 fotogramas = 480 fotogramas
#
##############################################################################
contador=1
let fotogramasredessociales=120
let fotogramaspantallafinal=480
# Calcula los finales de los bloques:
let finprimerbloque=$fotogramasentradilla+1+$fotogramastercio
let finsegundobloque=$finprimerbloque+1+$fotogramastercio
let fintercerbloque=$finsegundobloque+1+$fotogramasredessociales
let fincuartobloque=$fintercerbloque+1+$fotogramastercio
let finquintobloque=$fincuartobloque+1+$fotogramasredessociales
let finsextobloque=$finquintobloque+1+$fotogramastercio
let finseptimobloque=$finsextobloque+1+$fotogramaspantallafinal
for i in $(seq 1 $totalfotogramas)
do
if [ $contador -le $fotogramasentradilla ]
then
imagen=$(ls $directorioentradilla | head -n $contador | tail -n 1)
let contador++
elif [ $contador -gt $fotogramasentradilla ] && [ $contador -le $finprimerbloque ]
then
imagen=$imagenprincipal
let contador++
elif [ $contador -gt $finprimerbloque ] && [ $contador -le $finsegundobloque ]
then
imagen=$redessociales
let contador++
elif [ $contador -gt $finsegundobloque ] && [ $contador -le $fintercerbloque ]
then
imagen=$imagenprincipal
let contador++
elif [ $contador -gt $fintercerbloque ] && [ $contador -le $fincuartobloque ]
then
imagen=$redessociales
let contador++
elif [ $contador -gt $fincuartobloque ] && [ $contador -le $finquintobloque ]
then
imagen=$imagenprincipal
let contador++
elif [ $contador -gt $finquintobloque ] && [ $contador -le $finsextobloque ]
then
imagen=$imagenprincipal
let contador++
elif [ $contador -gt $finsextobloque ] && [ $contador -le $finseptimobloque ]
then
imagen=$pantallafinal
let contador++
fi
convert $imagen png:-
done | ffmpeg -f image2pipe -i - pistadevideo.mp4
ffmpeg -i pistadevideo.mp4 -i $1 -c:v copy -c:a copy $sinextension.mp4
rm pistadevideo.mp4
Ya sabemos cómo seleccionar aleatoriamente una tipografía para incluir texto en ImageMagick, pero nos puede ocurrir que, al ser aleatoria esa selección, nos elija una tipografía que sean dibujos, signos matemáticos o cualquier otra tipografía que no sea de letras, también nos puede mostrar una tipografía con un alfabeto distinto al nuestro o que no muestre bien algunos caracteres.
Yo siempre me fijo en cuatro caracteres clave: apertura de interrogación y exclamación, vocales con tilde y eñes.
Así pues, voy a usar una cadena de caracteres que tenga interrogaciones, una vocal con tilde y una eñe:
¿Leña? ¡Porrón!
Y como quiero ver qué tipografías que tengo instaladas en cada máquina muestran correctamente estos caracteres, hago los siguientes pasos:
#!/bin/bash
directoriotemporaltipografias="tipografias"
if [ ! -d directoriotemporaltipografias ]
then
mkdir $directoriotemporaltipografias
fi
for tipografia in $(convert -list font | grep "Font" | cut -d " " -f 4)
do
convert -pointsize 100 -font $tipografia label:"¿Leña? ¡Porrón!" $directoriotemporaltipografias/$tipografia.jpg
done
Veamos qué es lo que hace:
Indico que es un script en bash:
#!/bin/bash
Que el directorio con el que voy a trabajar se llama "tipografias", pero lo meto en una variable por si por cualquier motivo quiero cambiar de directorio:
directoriotemporaltipografias="tipografias"
Compruebo si existe o no ese directorio y si no existe, lo creo:if [ ! -d directoriotemporaltipografias ]
then
mkdir $directoriotemporaltipografias
fi
Hago un bucle en el que recorre todas las tipografías tal como vimos en el artículo anterior sobre tipografías en ImageMagick: y le digo que me genere una imagen por cada tipografía con la cadena antes indicada de "¿Leña? ¡Porrón!" guardando esas imágenes con el nombre de la tipografía utilizada en el directorio creado para tal efecto:for tipografia in $(convert -list font | grep "Font" | cut -d " " -f 4)
do
convert -pointsize 100 -font $tipografia label:"¿Leña? ¡Porrón!" $directoriotemporaltipografias/$tipografia.jpg
done
Con esto, tengo un directorio lleno de imágenes con cadenas de texto. Abro el directorio con un navegador de ficheros que muestre una previsualización de cada imagen y selecciono todas las imágenes que no me interesan por el motivo que sea, que generalmente es porque no escribe bien todos los caracteres indicados:
Otras veces es porque, aunque muestre correctamente los caracteres, no me parecen lo suficientemente legibles o son muy específicos de una determinada fecha: navideños, de Hallowen, con nieve...
Una vez borrados los que en una primera ronda en bruto me han parecido que no cubren mis necesidades (ojo, que cuando seleccionamos aleatoriamente una tipografía es bastante arriesgado poner a trabajar ese script y desentendernos, por lo que es mejor que, en caso de duda, borrar el fichero), paso a una segunda fase en la que miro una por una las tipografías.
A veces nos encontramos que una tipografía escribe correctamente los caracteres pero no nos queremos arriesgar a que un script la seleccione sin nuestra aprobación:
Estas tipografías muestran todos los caracteres, pero quizá no encajen en todos los contextos, por lo que las borro también.
Y una vez que he borrado todo lo que sobra, ejecuto un segundo script:
#!/bin/bash
directoriotemporaltipografias="tipografias"
for fichero in $(ls $directoriotemporaltipografias)
do
echo ${fichero%.*} >> tipografiasausar.txt
done
rm -r $directoriotemporaltipografias
rmdir $directoriotemporaltipografias
En el que le indico:
Que es un script bash:
#!/bin/bash
Que recoja los ficheros de un determinado directorio:directoriotemporaltipografias="tipografias"
Que recorra ese directorio fichero a fichero y quite la extensión de esos ficheros ${fichero%.*} e incluya el nombre sin extensión en un fichero de texto llamado tipografiasausar.txt añadiendo en cada pasada de for cada tipografía al texto ya existente en ese fichero (>>) for fichero in $(ls $directoriotemporaltipografias)
do
echo ${fichero%.*} >> tipografiasausar.txt
done
Que borre el contenido de ese directorio y el propio directorio para que no ocupe espacio en disco ni moleste una vez hecha la selección. rm -r $directoriotemporaltipografias
rmdir $directoriotemporaltipografias
Una vez creado el fichero tipografiasausar.txt para seleccionar aleatoriamente una línea de ese fichero lo podemos hacer con shuf. Así:
tipografia=$(shuf -n 1 tipografiasausar.txt)
Y así quedaría un script de ejemplo:
#!/bin/bash
tipografia=$(shuf -n 1 tipografiasausar.txt)
convert -pointsize 100 -fill Blue -font $tipografia label:"Automaticen\ny sean felices" automaticen.png
Estoy haciendo una serie de tutoriales de GIMP 2.10 y quería mostrar cómo van cambiando las imágenes al cambiar los valores de los deslizadores de las distintas herramientas que forman GIMP.
Una opción es capturar la pantalla con recordMyDesktop o ffmpeg y colgarlo tal cual. El problema de esto es que el entorno de GIMP ocupa un espacio que hace que la imagen se vea pequeña. Así que prefiero hacer un efecto PiP (Picture in Picture). Es decir, superponer una imagen, en este caso, la caja de la herramienta sobre otra imagen más grande, en este caso, la imagen que va cambiando según los valores dados en la caja de la herramienta.
Podría capturar la pantalla y con un editor de vídeo, por ejemplo, Kdenlive, duplicar la pista y hacer dos "crops": uno con la imagen y otro con la herramienta, superponer ambas y montar el vídeo. Aparte de que el proceso de edición es farragoso, debería también hacer muchas veces clic con el ratón. Demasiado trabajo... seguro que ImageMagick me permite hacer el mismo resultado con menos esfuerzo. Veamos cómo hacerlo:
1.- Para el primer ejemplo, he cogido la primera herramienta del menú de Color de GIMP. Y me aparece que los deslizadores van del -100 al 100. Así que, en lugar de hacer 201 clic con el ratón, voy a hacer un bucle con una secuencia del 0 al 200.
2.- En cada iteración voy a capturar la pantalla completa con import y hacer dos recortes con crop, por un lado, la imagen que va cambiando y por otro, la herramienta de turno, en este caso, "Balance de color".
3.- Como quiero que el vídeo esté en formato HD, paso la imagen a un tamaño de 1920x1080 píxeles.
4.- Superpongo las imágenes con composite y hago clic para aumentar el valor.
5.- Le digo a ffmpeg que haga un vídeo con todos los fotogramas
6.- Y borro las imágenes sobrantes
Ya he escrito previamente sobre todas las instrucciones de este script a excepción de xdotool, que es un comando para simular el manejo del ratón a través de línea de comandos. Permite cliquear con los distintos botones, mover la ruleta, mover el cursor, hacer doble clic... En este caso, como únicamente quiero que haga un clic con el botón izquierdo, usaré:
xdotool click 1
Así es como queda el script:
#!/bin/bash
for i in $(seq 0 200)
do
import -w root pantallazo.png
convert pantallazo.png -crop 1308x735+172+214 lienzo$1$i.png
convert pantallazo.png -crop 412x501+1497+242 -background Transparent -gravity Center -extent 600x600 deslizador$1$i.png
convert lienzo$1$i.png -resize 1920x1080 base.png
composite -gravity SouthEast deslizador$1$i.png base.png png:-
xdotool click 1
done | ffmpeg -f image2pipe -i - videos/$1.mp4
rm lienzo*
rm deslizador*
Y así queda el resultado:
¿Os han pedido alguna vez que tuiteeis algún gif de alguna película? A mi, sí. Hace unos minutos. Así que ya que voy a hacer un gif de una de mis películas favoritas, os cuento cómo hacerlo. Pero no es necesario que os pidan un gif de una película, si queréis hacer un gif a partir de un vídeo de YouTube, podéis seguir paso a paso este artículo. En caso de que tengáis el vídeo en vuestro ordenador, podéis obviar la parte de la descarga del vídeo.
Para descargar un vídeo de YouTube, o casi de cualquier plataforma de vídeo, incluídas muchas plataformas de vídeos para adultos, tenemos un comando súper eficiente para ello: youtube-dl. Su uso más básico es para descargar un vídeo (si quieren que escriba un artículo explicando cómo descargar sólo audio o una lista de vídeos, escríbanlo en los comentarios). Y para descargar un vídeo no necesitamos ni parámetros ni nada más que el comando y la url del vídeo. Como yo quiero tuitear sobre Machete (como digo, me han pedido un gif de una de mis películas favoritas, así que elijo esta escena de Machete):
https://www.youtube.com/watch?v=DTyeEB-ra7w
Y lo descargo con:
youtube-dl https://www.youtube.com/watch?v=DTyeEB-ra7w
Como he visto el vídeo de YouTube y sé que la parte de la que quiero extraer los fotogramas va de 00:14 a 00:21 uso el comando:
ffmpeg -i Machete\ improvises-DTyeEB-ra7w.mp4 -ss 00:14 -t 8 machete%04d.jpg
Voy a escribir dos frases: "Machete no manda mensajes" y "Machete improvisa". Para ver sobre qué fotogramas escribo cada una de las frases, voy a mirar dónde está el cambio de plano:
Hasta el fotograma machete0056.jpg voy a poner "Machete no manda mensajes" y en el resto, hasta el 200, "Machete improvisa":
#!/bin/bash
for i in $(seq 1 200)
do
if [ $i -lt 10 ]
then
sufijo=000$i.jpg
elif [ $i -lt 100 ]
then
sufijo=00$i.jpg
else
sufijo=0$i.jpg
fi
if [ $i -lt 56 ]
then
convert machete$sufijo -gravity South -font Luxi-Sans-Bold -pointsize 50 -fill White -stroke Black -strokewidth 3 -annotate +0+0 "MACHETE NO MANDA MENSAJES" fotograma$sufijo
else
convert machete$sufijo -gravity South -font Luxi-Sans-Bold -pointsize 70 -fill White -stroke Black -strokewidth 3 -annotate +0+0 "MACHETE IMPROVISA" fotograma$sufijo
fi
done
En este caso, la mayoría de los fotogramas son iguales o muy parecidos, así que voy a borrar unos cuantos. Al contrario que con ffmpeg, a la hora de hacer imágenes animadas con ImageMagick la numeración puede contener saltos.
Y además, tenemos la posibilidad de optimizar las imágenes para que el fichero resultante pese menos con -layers Optimize, que podemos usarlo así:
convert fotograma0* -delay 5 -loop 0 -layers Optimize macheteimprovisa.gif
Podéis ver el resltado en Twitter:
https://twitter.com/hacemoswebserie/status/1038551976131350528
Ya hemos visto cómo unir imágenes con -delay para crear un gif animado. Pero -delay, que es muy sencillo de usar, no permite definir cuántas veces queremos que se repita el bucle ni la velocidad a la que queremos que se muestren las imágenes que forman la animación.
Para estas dos funcionalidades tenemos:
-loop que permite definir el número de veces que queremos que se repita una determinada animación. Le indicamos el número de veces que queremos que se repita. Y si queremos que se repita infinitas veces, se lo indicamos con 0.
-delay que establece la velocidad a la que se mostararán las imágenes en centésimas de segundo. Es decir, si queremos que entre imagen e imagen pase un segundo, le indicaremos 100.
Así:
convert -delay 10 -loop 0 param* param.gif
Si quieren ver diversas fórmulas para crear imágenes que van mutando y luego unirlas en ficheros gif, pueden leer este hilo de Twitter:
https://twitter.com/hacemoswebserie/status/1037884393430429699
Supongamos que tenemos una serie de imágenes que queremos unir consecutivamente formando entre todas una animación en un único fichero gif. La forma más sencilla de hacerlo con ImageMagick es indicando a convert las imágenes que queremos unir, usando el parámetro -adjoin y diciéndole el fichero donde las queremos unir. Por ejemplo:
convert comp* -adjoin espaciosdecolor.gif
Con esto tendríamos un gif animado.
Si quieren ver cómo hice un gif con -adjoin y las imágenes generadas al descomponer una imagen en todos los canales de todos los espacios de color que utiliza ImageMagick y luego usarlos como máscaras para componer nuevas imágenes en dos colores, pueden leer este hilo de Twitter:
https://twitter.com/hacemoswebserie/status/1038386517935370241
En este artículo vamos a ver dos parámetros de convert que suelen ir de la mano: border y bordercolor. Uno genera un borde alrededor de una imagen, el otro define el color.
Vamos a ver un ejemplo de cómo trabajar con ellos. Pero primero crearemos una nueva imagen:
convert -size 500x200 xc:Black negro.png
Y ahora vamos a añadirle un borde uniforme de 5 puntos de color rojo:
convert negro.png -bordercolor Red -border 5x5 negroenmarcado.png
Es importante definir antes el color y después dibujar el borde. En caso de que no lo hagamos así, y escribamos antes -border que -bordercolor, conver dibujará el borde sin saber de qué color lo queremos. Y aunque se lo digamos después, el marco ya está dibujado. Veamos lo que pasa:
convert negro.png -border 5x5 -bordercolor Red negroenmarcado2.png
He dicho que quería un borde uniforme, pero he usado dos valores para el parámetro -border. Y estoy derrochando pulsaciones de teclado, ya que si usase -border con un sólo valor, me saldría esto:
convert negro.png -bordercolor Red -border 5 negroenmarcado3.png
Es decir, no hace falta escribir el valor de anchura y el de largura, aunque yo lo suelo poner, porque hay veces que necesito utilizar un grosor de borde distinto para las líneas horizontales que para las líneas verticales.
El primer valor es el grosor del marco vertical. El segundo valor, el grosor de las líneas horizontales del marco.
Veamos:
convert negro.png -bordercolor Red -border 1x15 negroenmarcado4.png
convert negro.png -bordercolor Red -border 15x1 negroenmarcado5.png
He puesto unos valores bien diferenciados de 1 y 15 para poder ver claramenta cómo hace las líneas.
Pero también podemos usar 0 como valor. Viene muy bien para delimitar un espacio y en imágenes superpuestas hace un efecto elegante:
convert negro.png -bordercolor Red -border 0x15 negroenmarcado6.png
Podemos usar también 3 y 4 valores con -border si queremos ser felices pensando que le estamos indicando el grosor de cada una de las líneas pero, aunque no da error, no atiende más que a los dos primeros valores.
convert negro.png -bordercolor Red -border 0x15x30x50 negroenmarcado7.png
Para conseguir eso, es mejor crear un lienzo con xc y anexarlo con append.
Lo que sí que podemos hacer, y puede darnos un resultado elegante, es concatenar varios border y bordercolor dentro de la misma instrucción.
convert negro.png -bordercolor Red -border 5x5 -bordercolor Black -border 5x5 -bordercolor Red -border 5x5 -bordercolor Black -border 5x5 negroenmarcado8.png