Script-Fu & Scheme

Script-Fu:

Scheme

Script installation

Script types

Gimp Scripts in Scheme

Scheme

        a variant on LISP.

        processes LISTS

        each list is a function with it's arguments

        evaluate functions to return values

 
 
(+ 3 4) => 7
 
 
(* 7 6) => 42
 
 
(+
 
  (* 3 4)
 
  (/ 1 3)) => 4
 
 
(define (borne x)
 
	(cond ((< x 0) 0)
 
	      ((> x 255) 255)
 
       (T x)))
 
 
(borne 278) => 255
 
(borne -12) => 0
 
(borne 236) => 236

Literals

Quoted values:

 
	'this
 
	'(255 127 63)
 
	(* '5 '5)
 
	(borne '235)

Variables

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

Local variables(*)

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

List Processing

Lists are made up of

        a first element (head) -- possibly a list

        the rest of the list (tail) -- always a list

 
 
(1 2 3) = (1 (2 (3 ())))
 
() 

The empty list () is a list!

(car '(1 2 3)) => 1

(car '((a b) 2 3)) = > (a b)

(cdr '(1 2 3)) => (2 3)

More list processing

 
(cdr (cdr '(1 2 3 4))) => (3 4)
 
(cddr '(1 2 3 4)) => (3 4)
 
 
(car (cdr (cdr '(1 2 3 4)))) => 3
 
(caddr '(1 2 3 4)) => 3
 
 
(cadr (quote (1 2 3 4))) => 2

NOTE: ALL GIMP FUNCTIONS RETURN LISTS

Loops

 
 
The only looping construct that exists in Script-Fu is while 
 
 
[Note: this constraint is due to the current scheme interpreter SIOD used for Script-Fu. Once the scheme interpreter as planned is changed to Guile,
 
more looping constructs will probably be added.] The while loop looks as follows: 
 
 
(while       (condition)
 
      (statement1)
 
      (statement2)
 
      :

)

GIMP Procedural DataBase (PDB)

Correspondence between script functions and GIMP interface.

Registering functions with Script-Fu

        Places script in interface menu

        registers parameter types and default values

        places command in PDB

 
(script-fu-register
 
 "my-func"	         ; name of func
 
 "Xtns/Script-Fu/My/Func" ; menu posn.
 
 "Does something"  ; help string
 
 "I. Am"           ; author
 
 "It's mine"       ; copyright
 
 "Today"           ; date
 
 ""                ;accepts any image type
 
 SF-VALUE "a" "0"  ; value param
 
 SF-COLOR "bk" '(0 0 0) ; color param
 
 SF-TOGGLE "inv" 0      ; boolean
 
)
 

Defining Script-Fu functions

 
(define (my-func a bk inv)
 
	 ; create image and layer
 
	 (set! img 
 
        (car (gimp-image-new a a RGB)))
 
  (set! layer
 
        (car (gimp-layer-new img a a
 
              RGB "layer 1" 100 NORMAL)))
 
  (gimp-image-disable-undo img)
 
  (gimp-image-add-layer img layer 0)
 
  (cond ((equalp inv 0)
 
         (gimp-palette-set-background bk))
 
	       (T
 
         (gimp-palette-set-background
 
          (invert bk))))
 
  (gimp-edit-fill img layer)
 
  (gimp-display-new img)
 
  (gimp-image-enable-undo img))

Working on current image

 
(script-fu-register "doit"
 
 "<Image>/Script-Fu/Me/doit"
 
 "Do something"
 
 "Me" "Mime" "today"
 
 "RGB*, GRAY*"
 
 SF-IMAGE "Image" 0
 
 SF-DRAWABLE "Layer" 0
 
 SF-VALUE "with" 5)
 
 
(define (doit img layer with)...)

Exemple1.

 
The following script uni.scm receives two parameters from the user, the size of the image, and a color and goes on to produce a uniform image of the requested size and the requested color. Not very useful, but it shows the essential steps in producing a script-fu script. (";" is a mark that the following is a comment)
 
 
; Define the function of the script and ;list its parameters
 
; The parameters will be matched with the ;parameters listed
 
; below in script-fu-register.
 
 
(define (uni-img size color)
 
   ; Create an img and a layer
 
   (set! img (car (gimp-image-new size size RGB)))
 
   (set! layer (car (gimp-layer-new img size size RGB "layer 1" 100 NORMAL)))
 
 
   ; The following is done for all scripts
 
   (gimp-image-disable-undo img)
 
   (gimp-image-add-layer img layer 0)
 
 
   ; Here is where the painting starts. We ;now have an image
 
   ; and layer and may paint in the layer ;through the PDB functions
 
   (gimp-palette-set-background color)
 
   (gimp-edit-fill img layer)
 
 
   ; The following is also done for all ;script
 
   (gimp-display-new img)
 
   (gimp-image-enable-undo img))
 
 
   ; Finally register our script with ;script-fu. 
 
 
   (script-fu-register "uni-img" 
 
      "<toolbox>/Xtns/Script-Fu/Tutorials/Uniform image"
 
      "Creates a uniform image"
 
      "Dov Grobgeld"
 
      "Dov Grobgeld"
 
      "1997"
 
      "" 
 
      SF-VALUE "size" "100"
 
      SF-COLOR "color" '(255 127 0))

Exemple2.

 
	Here is an example script which copies the current layer to a new layer, blurs it and inverts it. 
 
 
(define (script-fu-copy-blur                img drawable  blur-radius)
 
    ; Create a new layer
 
   (set! new-layer (car (gimp-layer-copy drawable 0)))
 
 
   ; Give it a name
 
   (gimp-layer-set-name new-layer "Gauss-blurred")
 
 
   ; Add the new layer to the image
 
   (gimp-image-add-layer img new-layer 0)
 
 
   ; Call a plugin to blur the image
 
   (plug-in-gauss-rle 1 img new-layer blur-radius 1 1)
 
 
   ; Invert the new layer
 
   (gimp-invert img 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"
 
      "1998"
 
 
      "RGB*, GRAY*"
 
      SF-IMAGE "Image" 0
 
      SF-DRAWABLE "Layer to blur" 0
 
      SF-VALUE "Blur strength" "5")
 

Exemple3.

 
Here's an example which draws horizontal lines, 16 pixels high, on an image: 
 
 
(set! y 0)
 
(while (< y size)
 
      (gimp-rect-select img 0 y size 16 REPLACE 0 0)
 
      (gimp-edit-fill img layer-one)
 
      (set! y (+ y 32)))

Exemple4.

 
Hereis an exemple to write a text in an image.
 
 
(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)
 
 
   ; Create the text. See DBbrowser for parameters of gimp-text.
 
   (set! text-float (car (gimp-text
 
            img
 
            drawable
 
            10 10
 
            "Hello world"
 
            0
 
            1
 
            30
 
            1
 
            "*" "Helvetica" "medium" "r" "*" "*")))
 
 
   ; Anchor the selection
 
   (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 Grobgeld"
 
      "1998"
 
      "RGB*, GRAY*"
 
      SF-IMAGE "Image" 0
 
      SF-DRAWABLE "Layer" 0)

Exemple5.

 
Copying a selection
 
 
To copy a selection, the command gimp-edit-copy is used. It places a copy of the selection contents in the cut-buffer. The contents of the
 
cut-buffer may then be pasted into a layer, the same layer or another one, and it is then pasted as a floating layer. 
 
 
In the following example the selection is copied, pasted into the same layer, offset a fixed distance, finally anchored. Try it by drawing a small blob in the
 
middle of the image, select the blob, and then call this script. 
 
 
(define (script-fu-sel-copy img
 
                            drawable)
 
 
   (gimp-undo-push-group-start img)
 
 
   (gimp-edit-copy img drawable)
 
   (set! sel-float (car (gimp-edit-paste img 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"
 
      "1998"
 
      "RGB*, GRAY*"
 
      SF-IMAGE "Image" 0
 
      SF-DRAWABLE "Layer" 0)