Publi

Automatizar efectos para crear vídeos en GIMP con script-fu

Tal vez hayamos utilizado GIMP es más de una ocasión, es un gran programa para retoque fotográfico en Linux. Por otro lado, para Linux no existen demasiados programas para creación de vídeo y efectos especiales, y los que hay son muy limitados.

Por eso, se puede dar el caso de que quisiéramos aplicar un efecto de GIMP dentro de un vídeo, pero no sólo en un fotograma estático (que importamos la imagen dentro del vídeo y listo), sino en una animación, modificando ligeramente el comportamiento del efecto fotograma a fotograma. Para ilustrar esto, he creado lo siguiente:

El texto está creado con OpenShot, así como la unión del texto con el resplandor. Para crear el resplandor, podemos hacerlo de forma más o menos fácil, yendo a filtros > Luces y sombras > Destello con degradado, y dentro de esa ventana podemos elegir las propiedades de dicho efecto, y aplicarlo. Una vez está bien, pero 180 veces (como en el ejemplo) variando los parámetros poco a poco, nos puede llevar varias horas. Por eso, vamos a utilizar la herramienta script-fu para automatizar este proceso.

Nuestro objetivo

La tarea a realizar es crear 180 fotogramas de un resplandor moviéndose a lo ancho de la pantalla, variando su radio, su ángulo y su color, para salvar la animación vamos a utilizar una secuencia de archivos png para poder utilizar la transparencia a la hora de componer el vídeo (que podamos ver cosas que están por detrás

¿Antes de comenzar, cómo funciona script-fu?

Es una utilidad de GIMP que utiliza un lenguaje derivado de lisp para automatizar tareas, en sí tenemos la sintaxis de lisp y algunas utilidades básicas, aunque GIMP introducirá muchas más utilidades. Los scripts, se almacenarán en archivos con la extensión scm (Scheme)

Para familiarizarnos con la herramienta, abriendo una sesión de GIMP podemos ir a Filtros > Script-fu > Consola y empezar a tocarlo.
Si no has tocado nunca lisp a lo mejor te cuesta un poco empezar, pero al final es muy fácil, todo va entre paréntesis y se separa con un espacio de la forma (orden argumento1 argumento2 … argumentoN)

Una vez abierta la ventana que comentaba anteriormente, lo primero que vamos a hacer es el hola mundo correspondiente, como viene en la imagen de la derecha:

1
(print "Hola mundo!")

Referencia rápida de LISP

Ahora podemos practicar creando operaciones:

1
2
3
4
5
6
7
8
; Sumamos 2 + 3
(+ 2 3)
; Sumamos 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
(+ 1 2 3 4 5 6 7 8 9)
; Multiplicamos 5 * 6 * 7
(* 5 6 7)
; 5 + 6 * 7 - (4 * 5 + 4)
(- (+ 5 (* 6 7)) (+ (* 4 5) 4))

Más o menos ya intuímos cómo funciona.

Ahora empieza lo bueno, si queremos crear variables:

1
2
3
4
5
6
7
(let*
   (
      (x 2)
      (y 4)
   )
   (+ x 3 y)
)

Es decir

1
2
3
4
5
6
7
8
9
10
11
12
(let*
   (
      (variable1 valor_inicial)
      (variable2 valor_inicial2)
      ...
      (variableN valor_inicialN)
   )
   (orden1)
   (orden2)
   ...
   (ordenN)
)

Donde las órdenes son líneas de programa en las que usamos variables.

Si queremos crear funciones:

1
2
3
4
5
6
(define (funcion argumento1 argumento2 ... argumentoN)
   (orden1)
   (orden2)
   ...
   (ordenN)
)

El punto fuerte de lisp son las listas, una lista la podemos definir como

1
2
3
(list 1 1 2 3 5 8 13 21 34)
; También puede definirse así:
'(1 1 2 3 5 8 13 21 34)

Ahora veremos métodos para extraer elementos de una lista, como son car (Content of Address part of Register; devolver el primer elemento de la lista), cdr (Content of Decremental part of Register; devolver todos menos el primero), nth (devuelve el n-ésimo elemento de la lista) y length para calcular la longitud.

1
2
3
4
5
6
7
8
(car '(1 1 2 3 5 8 13 21 34))
; 1
(cdr '(1 1 2 3 5 8 13 21 34))
; 34
(nth 4 '(1 1 2 3 5 8 13 21 34))
; 5
(length '(1 1 2 3 5 8 13 21 34))
; 9

Por último vamos a ver un bucle, script-fu sólo acepta bucles while, veamos un ejemplo:

1
2
3
4
5
6
7
8
9
(let*
   (
      (x 0)
   )
   (while (< x 10)
      (print x)
      (set! x (+ x 1))
    )
)

Con el script anterior contamos del 0 al 9, vamos incrementando x mientras éste sea menor que 10 y poniendo su valor en pantalla.

Hasta aquí una referencia rápida rapidísima del lenguaje, más o menos lo que necesitamos para el ejemplo.

Utilidades Script-fu


Ahora vamos a ver algunas utilidades de GIMP, podemos acceder al listado completo y a una referencia de todas las funciones desde Ayuda > Visor de procedimientos, pero aquí voy a comentar algunas funciones, para tener una referencia rápida:

Crear una nueva imagen(gimp-image-new ancho alto tipo)tipo = RGB, GRAY, INDEXED
Crear una nueva capa(gimp-layer-new ancho alto tipo nombre opacidad modo)tipo = RGB, ARGB u otro, y modo NORMAL-MODE (hay muchos modos, mirad la referencia)
Insertar capa en imagen(gimp-image-add-layer imagen capa posicion)posicion = 0, la posición con respecto a la capa actual
Eliminar una capa(gimp-image-remove layer imagen capa)
Mostrar una imagen(gimp-display-new imagen)
Salvar una imagen(gimp-file-save modo-de-ejecución imagen capa fichero ficheromodo de ejecución RUN-INTERACTIVE o RUN-NONINTERACTIVE. El fichero se repite 1 vez
Mostrar un mensaje(gimp-message mensaje)Será útil para mostrar mensajes fuera de la consola

También utilizaremos algunas utilidades de lisp básicas para conversión y concatenación:

Concatenar cadenas(string-append cadena1 cadena2 … cadenaN)
Convertir número a cadena(number->string numero)

¿Dónde situar nuestros scripts?

Mientras estamos creando el script está muy bien tener la consola, y mientras estamos en la consola podemos hacer todo lo que queramos, pero lo deseable es que nuestros scripts perduren y podamos ejecutarlos siempre que queramos. Para eso, debemos guardarlos con extensión scm en nuestro directorio personal /home/usuario/.gimp-2.6/scripts depende también de la versión de GIMP y de nuestro nombre de usuario.

Todo esto está muy bien, pero cómo creo un vídeo

Como nuestro objetivo es crear un vídeo exportándolo como secuencia de imágenes, debemos crear el efecto deseado en unas condiciones, e ir modificándolo poco a poco en cada fotograma. Para eso crearemos un bucle que irá generando cada fotograma y aplicará el efecto una y otra vez obteniendo así resultados diferentes en cada uno de los fotogramas.
Cada foto la iremos guardando en un directorio donde almacenaremos la secuencia entera en PNG. Los archivos serán del tipo nombre00001.png, nombre00002.png, …, nombreXXXXX.png; cuando vayamos a importarlos, muchos programas de vídeo tienen soporte para secuencias de imágenes, por ejemplo openShot, sólo seleccionando un archivo, podemos importar la secuencia entera.

El script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(define (pre-pad-number num-str size pad-str)
    (if (< (string-length num-str) size)
    (pre-pad-number (string-append pad-str num-str) size pad-str)
    num-str
     )
)

(define (poesia-crea-imagen filenamestart width height totalframes xs ys xe ye ts te vs ve lvs lve rs re)
    (let*
        (
            (image (car (gimp-image-new width height RGB)))
            (layer (car (gimp-layer-new image width height
                    RGBA-IMAGE "layer" 100 NORMAL-MODE)))
            (frame 0)
            (x xs)
            (y ys)
            (tone ts)
            (vector vs)
            (lvector lvs)
            (radio rs)
            (xinc (/ (- xe xs) totalframes))
            (yinc (/ (- ye ys) totalframes))
            (tinc (/ (- te ts) totalframes))
            (vinc (/ (- ve vs) totalframes))
            (rinc (/ (- re rs) totalframes))
            (lvinc (/ (- lve lvs) totalframes))
            (filename)
        )
       (while (< frame totalframes)
            (set! filename (string-append filenamestart (pre-pad-number (number->string frame) 5 "0") ".png"))
            (gimp-image-add-layer image layer 0)
            (plug-in-gflare RUN-NONINTERACTIVE image layer "Default" x y radio 50 tone vector lvector 0 0 0)
            ;(gimp-display-new image)
            (gimp-file-save RUN-NONINTERACTIVE image layer filename filename)
            (gimp-image-remove-layer image layer)
            (set! layer (car (gimp-layer-new image width height
                    RGBA-IMAGE "layer" 100 NORMAL-MODE)))
           
            (gimp-message (string-append filename " " (number->string x) "x" (number->string y)))
            (set! x (+ x xinc))
            (set! y (+ y yinc))
            (set! tone (+ tone tinc))
            (set! vector (+ vector vinc))
            (set! lvector (+ lvector lvinc))
            (set! radio (+ radio rinc))
            (set! frame (+ frame 1))
        )
       
    )
)

Este script utilizará plug-in-gflare para cada fotograma, así irá desplazando el resplandor, en este caso, modificando sus características en los diferentes fotogramas.
Tendremos muchos argumentos de entrada:

  • filenamestart: nombre de fichero con la ruta, pero sin la secuencia de números
  • width: ancho de la imagen
  • height: alto de la imagen
  • totalframes: fotogramas a generar
  • xs: posición X inicial
  • ys: posición Y inicial
  • xe: posición X final
  • ye: posición Y final
  • ts: tono inicial
  • te: tono final
  • vs: vector inicial
  • ve: vector final
  • lvs: longitud inicial del vector
  • lve: longitud final del vector
  • rs: radio inicial
  • re: radio final

Además, lo primero que hacemos en la declaración de variables, es definir las variables incremento, que será cuánto se modifica cada propiedad a lo largo del tiempo (en fotogramas). Como vemos, esos incrementos serán (propiedad_final – propiedad_inicial) / total_de_fotogramas

Ejecución del script

El script podemos ejecutarlo desde la consola de script-fu, pero vamos a hacerlo desde nuestro terminal, ya que no necesitamos iniciar el entorno gráfico de GIMP, sólo generar los archivos:

$ gimp -i -b ‘(poesia-crea-imagen “tests/luz” 720 576 180 -100 360 860 380 0 180 219 359 0 150 200 500)’ -b ‘(gimp-quit 0)’

Con esta línea cargaremos el script en GIMP en modo no interactivo (-i) y ejecutando el script (-b) cuando termine de ejecutar el primer script ejecutaremos el segundo (para salir del programa)

Como vemos generaremos 180 imágenes a 720×576 desde el punto -100×360 hasta el 860×380 pasando por todos los tonos (0º-180º), con el vector con ángulos de 219º a 359º y de longitud de 0 a 150. El radio crecerá de 200 a 500

Para terminar…

Importamos la secuencia de imágenes en nuestro editor de vídeo preferido, ya podemos empezar a experimentar!

También podría interesarte...

There are 4 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Robert /
    Usando Mozilla Firefox Mozilla Firefox 18.0 en Ubuntu Linux Ubuntu Linux

    Muy bueno tu blog, simpre me habia intersado eso de crear videos con gimp, pero nunca me meti de lleno. Lastima que en el video luego se veen “saltos”, supongo que es que gimp deve generar algun valor aleatorio en ese efecto, que no se conserva usando el script, pero me figuro que para la malloria de efectos i funciones de gimp eso no pasa así que resumiendo… muy bueno XD.

    En cualquier caso seguro que tambien es bueno para otro tipo de cosas, por ejemplo, si queremos que todas las imagenes de una carpeta se pasen a blanco y negro, se podria facilmente gracias a script-fu. Hmmm quiero aprender a hacer eso…

    Saludos!

    1. admin / Post Author
      Usando Mozilla Firefox Mozilla Firefox 18.0 en Ubuntu Linux Ubuntu Linux

      Gracias por tu comentario.

      En principio, los botes del vídeo, pueden ser también a la velocidad del efecto, el render tarda un poco y a lo mejor no quedó tan fino como creía. También le podía haber aplicado un poco de Gaussian Blur para difuminarlo un poco y que se note menos.

      Por lo que comentas de pasar todas las fotos de una carpeta a blanco y negro, eso lo podemos hacer más rápido con ImageMagick, por ejemplo:
      $ convert archivo_origen -colorspace Gray archivo_destino
      Si quieres convertirlos todos (cuidado que no guardas originales con esto, debes guardarlos antes)
      $ mogrify * -colorspace Gray

      Por ejemplo, para lo que puede ser útil esto puede ser para aplicar el GIMPresionist a los fotogramas de un vídeo, para que todos terminen con ese efecto, o para apilar una serie de efectos que sólo sea capaz de hacer GIMP, sobre todo porque es fácil crearlos y por Internet podemos encontrar muchos scripts. Será un poco más lento, pero no tenemos que calentarnos mucho la cabeza programando pixeles en C.

  3. Pingback: Cómo aplicar filtros de GIMP a un vídeo – Poesía Binaria /

Leave a Reply