Scheme básico

Texto e imágenes Copyright (C) 2002 Dov Grobgeld y no puede ser usado sin permiso del autor.

Intención

Una de las mejores características de GIMP es que se puede acceder a todas sus funcionalidades mediante códigos. El mayor lenguaje de programación para el GIMP, que ha sido adjuntado a el actualmente, es el SCHEME. Este documento intentará ser una introducción de ayuda al SCHEME, enseñando las esencias para escribir códigos Script-fu, sin entrar en teorías del lenguaje de programación, típicas de otras referencias al SCHEME.

1. Expresiones

Scheme es una variante de lisp y todas sus expresiones están entre paréntesis. Ejemplo, una lista que calculará la suma de 3 y 4 se escribe

(+ 3 4)

El signo + es la función de adición y 3 y 4 son el primer y segundo parámetros de esta función. Las Expresiones pueden ser anidadas, así la expresión (3+4)*(5/6), en SCHEME, se escribiría

(* (+ 3 4) (/ 5 6))

Los espacios en blanco no tienen importancia, así la expresión de encima , también, se podría escribir

(* (+ 3 4) (/ 5 6))

2. Funciones

Aparte de las cuatro funciones aritméticas representadas con los símbolos +-*/, hay un montón de funciones construidas en el lenguaje. Todas tienen la forma

(foo param1 param2 ...)

Funciones adicionales pueden ser definidas por el usuario mediante la palabra define. Ejemplo, una función que calcula el valor al cuadrado de un argumento se podría declarar así

(define (square x) (* x x))

y se puede llamar a la función mediante

(square 5)

3. Variables y listas

Las Variables pueden declararse y configurarse mediante el comando set!. (Estas variables serán globales pero esto no debería molestar al programador casual de GIMP). Aquí hay un par de asignaciones:

(set! grey_value 85) (set! angle (* (/ 30 180) 3.141)

Lisp y sus variantes hacen un uso pesado de listas. Script-fu no es una excepción y usa, por ejemplo, una lista de tres elementos para escribir un color RGB. El color naranja se escribiría así

'(255 127 0)

El signo ' es necesario para decir que es una lista literal. Si se omite, el signo ' , SCHEME buscaría una función con el nombre 255 y le enviaría dos parámetros 127 y 0, lo que, obviamente, no es lo que queremos.

Para crear una variable llamada orange con los valores de encima y, entonces, configurar el color de fondo con el, deberíamos hacer

(set! orange '(255 127 0)) (gimp-set-background-color orange)

3.1 car, cdr y amigos (*)

Una lista en SCHEME está, siempre, compuesta de una cabeza y una cola. La cabeza es la primera entrada en la lista, y la cola es la lista de el resto de elementos. Esto significa que la lista (255 127 63) realmente es (255(127(63()))), pero SCHEME permite el formato anterior como atajo. La función car se usa para volver a la cabeza de la lista y la cdr (normalmente, pronunciada cudder) se usa para obtener la cola de la lista.

[Lo siguiente es una prueba de las funciones de arriba que podrían, interactivamente, llevarse a la consola Script-fu.]

=> (set! color '(255 127 63)) (255 127 63) => (car color) 255 => (cdr color) (127 63)

Para obtener el componente azul de un color es necesario aplicar la función cdr dos veces y entonces la función car.

=> (car (cdr (cdr color))) 63

Esto es un inconveniente para escribir. Por lo tanto allí, tienen que estar definidas abreviaciones de la forma cadr, cddr, caddr, et., que concatenen las operaciones descritas arriba. La expresión anterior podría, mucho más convenientemente, ser escrita:

=> (caddr color) 63

Para el escritor de Script-fu, uno de los más importantes usos de la función car es acceder a los valores devueltos desde las funciones incorporadas en GIMP. Todas las funciones Gimp devuelve una lista, y, siempre, si las listas contienen solo un elemento se debe acceder con car. Este es un ejemplo, el caso para las importantes funciones de GIMP: Nueva imagen y Nueva capa, usadas abajo.

3.2 Variables locales (*)

Los programadores más experimentados de SCHEME , por lo general, usan variables locales en vez de las variables globales descritas encima. Este es considerado mejor para practicas de programación y esta construcción debería ser reconocida para ser capaces de leer otros códigos de Script-Fu.

Las variables locales son declaradas mediante la palabra let como en el ejemplo siguiente:

(let* ((a 3) (b 4)) ((* a b)))

Aquí a y b tienen un alcance local y retienen sus valores solo hasta el cierre "paréntesis" cerrados juntándolos antes de let*.

4. GIMP PDB

Toda la funcionalidad de GIMP está disponible mediante la base de datos de procedimientos (PDB). Cada función de la base de datos de procedimientos tiene una función correspondiente en SCHEME. Ejemplo:

(gimp-image-new 100 150 RGB)

produce una imagen nueva del tipo RGB y un tamaño de 100x150

Se pueden acceder a todas las funciones de PDB mediante el Examinador de procedimientos que está disponible desde el menú principal Exts-> Examinador de procedimientos... Ejemplo, la entrada para uni-img en el Examinador de procedimientos, la cual se definirá en el ejemplo de abajo, será algo parecido a esto:

Para los programadores Script-Fu, esta información muestra que uni-img puede ser llamada con tres parámetros de los tipos INT32, STRING y COLOR. Los diferentes tipos se explicarán abajo.

5. Registrando el código con Script-Fu

Después que una función ha sido escrita tiene que registrarse con script-fu antes de que pueda ser usada. Esto se hace mediante la función SCHEME sript-fu register. El registro tiene las siguientes propósitos:

  1. Encontrar el lugar del script en los menús Sript-Fu.

  2. Decirle al script el tipo de parámetros que el script toma y da a estos parámetros predeterminados.

  3. Registrar los script como un comando en la PDB.

El último punto de arriba, actualmente, quiere decir que un script, desde el punto de vista de GIMP,de ninguna manera es diferente de construir un comando o un comando de plug-in. Mientras un comando esté registrado en la PDB puede ser llamado por un script o plug-in.

Los parámetros del script-fu register se pueden dividir en dos grupos. El primer grupo de siete parámetros deben darse siempre. Estos son:

  1. El nombre de la función lisp.

  2. La posición del script en los menús del Gimp.

  3. Una variable de ayuda describiendo las funciones del scrip.

  4. El autor.

  5. El copyright.

  6. La fecha.

  7. Lista de tipo de imágenes válidas para el script. Esto solo tiene un significado sobre operaciones de scripts sobre imágenes que todavía existen.

Después de que estos siete parámetros han sido dados, sigue una lista con los parámetros requeridos por el script. Cada parámetro es dado como un grupo de tres artículos:



  1. El tipo de parámetros. Tipos válidos son

    SF-COLOR
    Un color RGB
    SF-TOGGLE
    Un valor verdadero o falso.
    SF-IMAGE
    SF-DRAWABLE
    SF-VALUE
    Un valor escalar, variable, integro o un punto flotante.
  2. Una etiqueta para un script que representa preguntar por parámetros.

  3. Un valor predeterminado.

6. Un script comentado

El siguiente script, uni.scm, recibe dos parámetros del usuario, el tamaño de la imagen y el color, y va a producir una imagen uniforme con el tamaño y el color requeridos. No demasiado útil, pero muestra los pasos esenciales en la producción de un código script-fu.

; Define las funciones del script y lista sus parámetros ; Los parámetros se igualarán con los parámetros dados ; abajo en script-fu-register. (define (uni-img size color) ; Crear una imagen img y una capa layer (set! img (car (gimp-image-new size size RGB))) (set! layer (car (gimp-layer-new img size size RGB "layer 1" 100 NORMAL))) ; Lo siguiente se hace para todos los scripts (gimp-image-undo-disable img) (gimp-image-add-layer img layer 0) ; Aquí es donde empieza a pintar. Ahora tenemos una imagen ; y una capa y podremos pintar sobre la capa con las funciones PDB. (gimp-palette-set-background color) (gimp-edit-fill layer BG-IMAGE-FILL) ; Lo siguiente se hace, también, para todos los scripts (gimp-display-new img) (gimp-image-undo-enable img)) ; Finalmente registrar nuestro script con script-fu. (script-fu-register "uni-img" "<Toolbox>/Xtns/Script-Fu/Tutorials/Uniform image" "Creates a uniform image" "Dov Grobgeld <dov@imagic.weizmann.ac.il>" "Dov Grobgeld" "2002-02-12" "" SF-VALUE "size" "100" SF-COLOR "color" '(255 127 0))

Para probar el script guardalo en $HOME/.gimp-x.x/scripts/uni.scm y entonces selecciona Exts -> Script-Fu -> Refrescar:

El script Uniform image debería aparecer, ahora, en el menú Exts -> Script-Fu -> Tutoriales -> Uniform image. Seleccionando este script resulta la siguiente ventana :

Aceptando los parámetros predefinidos mediante el botón OK , nos da la siguiente nueva imagen:

También, es posible acceder a este script a través de la consola Script-Fu tecleando el comando

(uni-img 100 '(0 255 127))

6.1 Colgar un script en el menú de la imagen

El script uni-img fue situado bajo Exts/... en la ventana principal de GIMP. Esto se hace para crear una imagen nueva que es independiente de las imágenes recientes. También, es posible crear un script que trabaje sobre una imagen existente. Si en script-fu register como segundo argumento se escribe:

<Image>/Script-Fu/...

Entonces el script estará disponible mediante el menú de GIMP que se puede lanzar pinchando con el botón derecho del ratón sobre la imagen. El script debe tener, también, como primer y segundo argumentos un SF-IMAGE y un SF-DRAWABLE.

Aquí está un ejemplo de script que copia la capa actual a una capa nueva, la desenfoca y la invierte.

; Un script de ejemplo que desenfoca una imagen de acuerdo a un blur radius. ; Ilustra como colgar un script en el menú de la imagen, y ; como un plug-in puede ser llamado. (define (script-fu-copy-blur img drawable blur-radius) ; Crear una capa nueva (set! new-layer (car (gimp-layer-copy drawable 0))) ; Darle un nombre (gimp-layer-set-name new-layer "Gauss-blurred") ; Añadir la nueva capa a la imagen (gimp-image-add-layer img new-layer 0) ; Llamar a un plug-in para desenfocar la imagen (plug-in-gauss-rle 1 img new-layer blur-radius 1 1) ; Invertir la capa nueva (gimp-invert new-layer) ; Flush the display (gimp-displays-flush) ) (script-fu-register "script-fu-copy-blur" "<Image>/Script-Fu/Tutorial/copy-blur" "Copy and blur a layer" "Dov Grobgeld" "Dov Grobgeld" "2002" "RGB*, GRAY*" SF-IMAGE "Image" 0 SF-DRAWABLE "Layer to blur" 0 SF-VALUE "Blur strength" "5")




7. Pintando áreas con selecciones

En uni-img, llamamos al procedimiento gimp-edit-fill para rellenar una imagen entera. Mirando la información de gimp-edit-fill en Examinador de procedimientos, encontramos lo siguiente:

Si tenemos una selección activa cuando se llama a gimp-edit-fill, solo la selección es pintada. Hay varias maneras de elegir una selección como puede verse cuando buscamos por una "select" en la PDB. Usaremos gimp-rect-select, cuya entrada en la PDB se ve como sigue:

Un simple uso de esta función la cual selecciona el rectángulo (x, y, ancho, alto)=(0, 25, 100, 50), pinta esa región de azul y realiza la selección se ve como sigue:

(gimp-rect-select img 0 25 100 50 REPLACE 0 0) (gimp-palette-set-background '(0 0 255)) (gimp-edit-fill layer BG-IMAGE-FILL) (gimp-selection-none img)



8. Loops

La única construcción looping que existe en Script-Fu es while

[Nota: esto se da en el actual interprete de SCHEME, SIOD, usado en Script-Fu. Una vez que el interprete de SCHEME planea cambiar a Guile,provablemente, serán añadidas más construcciones looping ]. El loop while se ve como sigue

(while (condition) (statement1) (statement2) : )

Aquí un ejemplo que dibuja líneas horizontales, de 16 pixels, en una imagen:

(set! y 0) (while (< y size) (gimp-rect-select img 0 y size 16 REPLACE 0 0) (gimp-edit-fill layer-one BG-IMAGE-FILL) (set! y (+ y 32)))


9. Selecciones flotantes

Cuando pegas una imagen del portapapeles o cuando creas un texto en un dibujable, el resultado no se pone directamente en el dibujable. En lugar de eso la pone en una capa especial temporal conocida como una selección flotante. La selección flotante puede ser manipulada de varias maneras, y finalmente mezcladas en su capa asociada, un proceso conocido como anclar.

9.1 Hello World - escribiendo texto en una imagen

Cuando creamos texto con el comando gimp-text, el texto, siempre, se pone en una capa temporal. Esta capa temporal, entonces, tiene que ser ancladas. Aquí está un ejemplo de creación de texto que es pegado en dibujable activo:

; Un ejemplo, un script que escribe una cadena fija en la imagen ; actual. (define (script-fu-hello-world img drawable) ; Start an undo group. Everything between the start and the end will ; be carried out if an undo command is issued. (gimp-undo-push-group-start img) ; Crear el texto. Ver Examinador de procedimientos para los parámetros de gimp-text. (set! text-float (car (gimp-text-fontname img drawable 10 10 "Hello world" 0 1 50 0 "-*-utopia-*-r-*-*-*-*-*-*-*-*-*-*"))) ; Anclar la selección (gimp-floating-sel-anchor text-float) ; Complete the undo group (gimp-undo-push-group-end img) ; Flush output (gimp-displays-flush)) (script-fu-register "script-fu-hello-world" "<Image>/Script-Fu/Tutorial/Hello World" "Write Hello World in the current image" "Dov Grobgeld <dov@imagic.weizmann.ac.il>" "Dov Grobgeld" "2002-02-12" "RGB*, GRAY*" SF-IMAGE "Input Image" 0 SF-DRAWABLE "Input Drawable" 0)

Este script muestra otra característica que no hemos mostrado antes. La posibilidad de crear un grupo deshacer. Todos los comandos entre los comandos gimp-undo-push-group-begin y gimp-undo-push-group-end son deshechos juntos si el comando deshacer es activado

9.2 Copiando una selección

Para copiar una selección, se usa el comando gimp-edit-copy. Coloca una copia del contenido de la selección en el búfer cortar. El contenido del búfer cortar puede entonces ser pegados en una capa, la misma capa o otra, y es pegada, entonces, como una capa flotante.

En el siguiente ejemplo, la selección es copiada, pegadas en la misma capa, offset a distancia fija, y, finalmente, anclada. Inténtalo dibujando un pequeño globo en el medio de la imagen, selecciónalo, y llama a este script.

; An example of how to create a floating layer and how to ancor it. (define (script-fu-sel-copy img drawable) (gimp-undo-push-group-start img) (gimp-edit-copy drawable) (set! sel-float (car (gimp-edit-paste drawable FALSE))) (gimp-layer-set-offsets sel-float 100 50) ; Anchor the selection (gimp-floating-sel-anchor sel-float) ; Complete the undo group (gimp-undo-push-group-end img) ; Flush output (gimp-displays-flush)) (script-fu-register "script-fu-sel-copy" "<Image>/Script-Fu/Tutorial/Selection Copy" "Copy the selection into the same layer" "Dov Grobgeld" "Dov Grobgeld" "2002-02-12" "RGB*, GRAY*" SF-IMAGE "Image" 0 SF-DRAWABLE "Layer" 0)

Traducido por AntI (Ant.Ign at gmail), Octubre de 2005 – Agradezco a Dov Grobgeld la autorización para usar y traducir su tutorial.