One of the wonderful features of GIMP is that it all its functionality may be accessed through scripting. The major scripting language for the GIMP that has been attached to it today is Scheme. This document will try to be a brief introduction to Scheme, just teaching the essentials in order to write script-fu scripts, without getting into the programming language theory that is so typical of other Scheme references.
Scheme is a lisp variants and all expressions are surrounded by parens. E.g. a list which will calculate the sum of 3 and 4 is written(+ 3 4)The + sign is the addition function and 3 and 4 are the first and second parameters to this function. Expressions may be nested, so the expression (3+4)*(5/6) would in Scheme be written(* (+ 3 4) (/ 5 6))White space has no importance so the above expression may as well be written:(* (+ 3 4) (/ 5 6))
Aside from the four arithmetic functions that are represented through the symbols + - * / there are lots of other functions built into the language. All of them have the form(foo param1 param2 ...)Additional functions may be defined by the user through the define keyword. E.g. a function that calculates the square value of its single argument may be declared like this(define (square x) (* x x))and this function may be called through(square 5)
Variables may be declared and set through the set! command. (These variables will be global but this should not bother the casual gimp programmer). Here are a couple of assignments:(set! grey_value 85) (set! angle (* (/ 30 180) 3.141)Lisp and its variants make heavy use of lists. Script-fu is no exception and it uses e.g. a list of three elements to write a RGB color. E.g. the color orange would be written'(255 127 0)The ' sign is necessary in order to tell scheme that this is a literal list. If the ' was omitted scheme would try to look up a function with the name 255 and send it the two parameters 127 and 0, which is obviously not what we wants.To create a variable called orange with the above value and then set the background color to it we may do
(set! orange '(255 127 0)) (gimp-set-background-color orange)
A list in Scheme is always composed of a head and a tail. The head is the first entry in the list, and the tail is the list of the rest of the elements. This means that the list(255 127 63) really means(255 (127 (63 ()))) but Scheme allows the previous form as a shortcut. The car function is used to return the head of the list and the cdr (usually pronounced cudder) is used to get the tail of the list.[The following is a test of the above functions which may interactively be conducted in the Script-Fu console.]
=> (set! color '(255 127 63)) (255 127 63) => (car color) 255 => (cdr color) (127 63)To get the blue component of a color it is necessary to apply the cdr function twice and then the car function.=> (car (cdr (cdr color))) 63This is very unconvenient to write. Therefore there have been defined abreviations of the form cadr, cddr, caddr, etc that concatinate the operations described above. The previous expression may therefore much more conveniently be written:=>(caddr color) 63For the Script-Fu writer one of the most important uses of the car function is to access the returned values from the built-in gimp functions. All gimp-functions return a list, and even if the list contains only one element it must be accessed by car. This is e.g. the case for the important functions gimp-new-image and gimp-new-layer used below.
More experienced scheme programmers mostly use local variables instead of the global variables described above. This is considered better programming practice and this construct should be recognized in order to be able to read others ScriptFu scripts.Local variables are declared through the the let keyword as in the following example:
(let* ((a 3) (b 4)) ((* a b)))Here a and b have a local scope and retain their values only up to the closing paren matching the one before let* .
All functionality of GIMP is available through the procedural database (PDB). Each procedural database function has a corresponding scheme function mapping. E.g.(gimp-image-new 100 150 RGB)produces a new gimp image of type RGB and size 100x150.All teh functions of the PDB may be accessed through the DB browser that is available from the main menu through Xtns>DB BROWSER.... E.g. the DB Browser entry for uni-img, which we will define in the example below looks like this:
![]()
For the Script-Fu programmer this information shows that uni-img may be called with three parameters of the types INT32, STRING and COLOR. The different types will be explained below.
After a function has been written it has to be registered with script-fu before it can be used. This is done through the scheme function script-fu-register. The registering has following purposes:The last point above actually means that a script is from Gimp's viewpoint in no way different from a built-in command or a plugin command. As long as a command is registered in the PDB it can be called by any script or plugin.
- Choose the place of the script in the Script-Fu pulldown menus.
- Tell script-fu the type of parameters the script takes and give these parameters default values.
- Register the script as a command in the PDB.
The parameters of script-fu-register may be divided into two groups. The first group of seven parameters must always be given. These are:
After these seven parameters have been given, follows a list of the parameters required by the script. Each parameter is given as a group of three items:
- The name of the lisp function.
- The position of the script in the gimp menus.
- A help string describing the function of the script.
- The script author.
- The script copyright.
- Script date.
- List of valid image types for the script. This only has a meaning on scripts operating on images that already exist.
- The type of the parameter. Valid types are
- SF-COLOR
- An RGB color.
- SF-TOGGLE
- A true or false value.
- SF-IMAGE
- SF-DRAWABLE
- SF-VALUE
- Any scalar value, string, integer, or floating point.
- A label for script-fu to display when querying for the parameter.
- A default value.
The following script uni.scm receives two parameter 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.
uni.scm 1: ; Define the function of the script and list its parameters 2: ; The parameters will be matched with the parameters listed 3: ; below in script-fu-register. 4: (define (uni-img size color) 5: ; Create an img and a layer 6: (set! img (car (gimp-image-new size size RGB))) 7: (set! layer (car (gimp-layer-new img size size 8: RGB "layer 1" 100 NORMAL))) 9: 10: ; The following is done for all scripts 11: (gimp-image-undo-disable img) 12: (gimp-image-add-layer img layer 0) 13: 14: ; Here is where the painting starts. We now have an image 15: ; and layer and may paint in the layer through the PDB functions. 16: (gimp-palette-set-background color) 17: (gimp-edit-fill layer BG-IMAGE-FILL) 18: 19: ; The following is also done for all script 20: (gimp-display-new img) 21: (gimp-image-undo-enable img)) 22: 23: ; Finally register our script with script-fu. 24: (script-fu-register "uni-img" 25: "<Toolbox>/Xtns/Script-Fu/Tutorials/Uniform image" 26: "Creates a uniform image" 27: "Dov Grobgeld <dov@imagic.weizmann.ac.il>" 28: "Dov Grobgeld" 29: "2002-02-12" 30: "" 31: SF-VALUE "size" "100" 32: SF-COLOR "color" '(255 127 0))
To test the script save it in $HOME/.gimp-1.2/scripts/uni.scm and then select Xtns/Script-Fu/Refresh:The script Uniform image should now appear in the pulldown menu Xtns/Script-Fu/Tutorials/Uniform image. Selecting this script results in the following popup: ![]()
![]()
Accepting these default parameters through the OK button gives us the following new image:
![]()
It is also possible to access this script through the Script-Fu console by typing the command
(uni-img 100 '(0 255 127))
In the uni-img script it was placed under Xtns/... in the main Gimp window. This is done to create a new image that is independant of earlier images. It is also possible to create a script which works on an already existing image. If in script-fu-register as the second argument is written:<Image>/Script-Fu/...then the script will be available through the gimp menu that is launched by the right mouse button over an image. Such script must also have as their first and second argument a SF-IMAGE and a SF-DRAWABLE.Here is an example script which copies the current layer to a new layer, blurs it and inverts it.
copy-blur.scm 1: ; An example script that blurs an image according to a blur radius. 2: ; It illustrates how to hang a script in the image menu, and 3: ; how a plug-in may be called. 4: (define (script-fu-copy-blur img 5: drawable 6: blur-radius) 7: ; Create a new layer 8: (set! new-layer (car (gimp-layer-copy drawable 0))) 9: 10: ; Give it a name 11: (gimp-layer-set-name new-layer "Gauss-blurred") 12: 13: ; Add the new layer to the image 14: (gimp-image-add-layer img new-layer 0) 15: 16: ; Call a plugin to blur the image 17: (plug-in-gauss-rle 1 img new-layer blur-radius 1 1) 18: 19: ; Invert the new layer 20: (gimp-invert new-layer) 21: 22: ; Flush the display 23: (gimp-displays-flush) 24: ) 25: 26: (script-fu-register "script-fu-copy-blur" 27: "<Image>/Script-Fu/Tutorial/copy-blur" 28: "Copy and blur a layer" 29: "Dov Grobgeld" 30: "Dov Grobgeld" 31: "2002" 32: "RGB*, GRAY*" 33: SF-IMAGE "Image" 0 34: SF-DRAWABLE "Layer to blur" 0 35: SF-VALUE "Blur strength" "5")
In uni-img we called the procedure gimp-edit-fill to fill the whole image. Looking at the info for gimp-edit-fill in the DB browser we find the following:Thus, if we have a selection active when the gimp-edit-fill is called only the selection is painted. There are lots of ways of choosing a selection as can be seen when searching for a ``select'' in the PDB. We will use gimp-rect-select, whose entry in the PDB looks as follows:
Name: gimp-edit-fill Blurb: Fill selected area of drawable In: DRAWABLE drawable The drawable to fill from INT32 fill_type The type of fill: FG_IMAGE_FILL (0), BG_IMAGE_FILL (1), WHITE_IMAGE_FILL (2), TRANS_IMAGE_FILL (3), NO_IMAGE_FILL (4) Help: This procedure fills the specified drawable with the fill mode. If the fill mode is foreground, the current foreground color is used. If the fill mode is background, the current background color is used. Other fill modes should not be used. This procedure only affects regions within a selection if there is a selection active. A simple use of this function which selects the rectangle
Name: gimp-rect-select Blurb: Create a rectangular selection over the specified image In: IMAGE image The image FLOAT x x coordinate of upper-left corner of rectangle FLOAT y y coordinate of upper-left corner of rectangle FLOAT width the width of the rectangle: width > 0 FLOAT height the height of the rectangle: width > 0 INT32 operation the selection operation: {ADD (0), SUB(1), REPLACE (2), INTERSECT (3) } INT32 feather feather option for selections FLOAT feather_radius radius for feather operation Help: This tool creates a rectangular selection over the specified image. The rectangular region can be either added to, subtracted from, or replace the contents of the previous selection mask. If the feather option is enabled, the resulting selection is blurred before combining. The blur is a gaussian blur with the specified feather radius. (x,y,width,height)=(0,25,100,50) , paints this region blue, and releases the selection looks as follows:(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)
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) : )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 layer-one BG-IMAGE-FILL) (set! y (+ y 32)))
When pasting an image from the clipboard, or when creating text in a a drawable, the result is not put directly in the drawable. Instead it is put into a special temporary layer known as a floating selection. The floating selection may be manipulated in several ways, and finally it is merged into its associated layer, a process known as anchoring.
When creating text through the gimp-text command, the text is always put into a temporary layer. This temporary layer then has to be anchored. Here is an example of creating some text which is pasted into the current drawable:
hello-world.scm 1: ; An example script that writes a fixed string in the current 2: ; image. 3: (define (script-fu-hello-world img drawable) 4: 5: ; Start an undo group. Everything between the start and the end will 6: ; be carried out if an undo command is issued. 7: (gimp-undo-push-group-start img) 8: 9: ; Create the text. See DBbrowser for parameters of gimp-text. 10: (set! text-float (car (gimp-text-fontname 11: img 12: drawable 13: 10 10 14: "Hello world" 15: 0 16: 1 17: 50 18: 0 19: "-*-utopia-*-r-*-*-*-*-*-*-*-*-*-*"))) 20: 21: ; Anchor the selection 22: (gimp-floating-sel-anchor text-float) 23: 24: ; Complete the undo group 25: (gimp-undo-push-group-end img) 26: 27: ; Flush output 28: (gimp-displays-flush)) 29: 30: (script-fu-register "script-fu-hello-world" 31: "<Image>/Script-Fu/Tutorial/Hello World" 32: "Write Hello World in the current image" 33: "Dov Grobgeld <dov@imagic.weizmann.ac.il>" 34: "Dov Grobgeld" 35: "2002-02-12" 36: "RGB*, GRAY*" 37: SF-IMAGE "Input Image" 0 38: SF-DRAWABLE "Input Drawable" 0)
This script shows another feature we haven't mentioned before. The possibility of creating an undo group. All the commands between the commands gimp-undo-push-group-begin and gimp-undo-push-group-end are undone together if the undo command is issued.
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.
sel-copy.scm 1: ; An example of how to create a floating layer and how to ancor it. 2: (define (script-fu-sel-copy img 3: drawable) 4: 5: (gimp-undo-push-group-start img) 6: 7: (gimp-edit-copy drawable) 8: (set! sel-float (car (gimp-edit-paste drawable FALSE))) 9: (gimp-layer-set-offsets sel-float 100 50) 10: 11: ; Anchor the selection 12: (gimp-floating-sel-anchor sel-float) 13: 14: ; Complete the undo group 15: (gimp-undo-push-group-end img) 16: 17: ; Flush output 18: (gimp-displays-flush)) 19: 20: 21: (script-fu-register "script-fu-sel-copy" 22: "<Image>/Script-Fu/Tutorial/Selection Copy" 23: "Copy the selection into the same layer" 24: "Dov Grobgeld" 25: "Dov Grobgeld" 26: "2002-02-12" 27: "RGB*, GRAY*" 28: SF-IMAGE "Image" 0 29: SF-DRAWABLE "Layer" 0)