Skip to content


This tutorial describes the creation little smiling face by the meaning of a scheme script fu.
smiley script

I have choose this example because it's implement simple selection func, filling and one plug ins, whose are imho the simplest and first thing to learn in script fu. I accorded to you that otherwise this script is completly useless =) This tutorial is not indend to be linear but want to explain a given script

this script take an arg : 'radius' , declared as a SF-VALUE at end of script-fu registration

NB : car is in scheme the first part of a list, and cdr the rest. same way cadr is the first part of the rest...

step 1

first a perfect round ellipse selection
(gimp-ellipse-select img 10 10 (* radius 2) (* radius 2) REPLACE TRUE 0 0)

here we use img, which is the current active image. We have created it by
(img (car (gimp-image-new (+ (* radius 2) 20) (+ (* radius 2) 20) RGB)))

this declaration will create img. here is it locked in a "let" in view to be reuse. (I want to open the script step by step...here one part, other come after)

at end of script we'll make this image visible
(gimp-display-new img)

step 2

now we want to fill this selection with yellow
(gimp-palette-set-foreground '(255 255 0))

in intention to do that we'll loose the foreground color, so we'll save it in the upper let
(old-bg-color (car (gimp-palette-get-background)))
(old-fg-color (car (gimp-palette-get-foreground)))

and restitute at end of script
(gimp-palette-set-foreground old-fg-color)
(gimp-palette-set-background old-bg-color)

step 3

now filling
(gimp-bucket-fill shape FG-BUCKET-FILL NORMAL-MODE 100 0 FALSE 0 0)

in intention to fill we need a "drawable" layer. this layer is created in the upper let by :
(shape (car (gimp-layer-new img (+ (* rayon 2) 20) (+ (* rayon 2) 20) RGBA_IMAGE "Shape" 100 NORMAL)))

add to img by :
(gimp-image-add-layer img shape 0)

cleared by :
(gimp-edit-clear shape)

step 4

so now the smile and the eyes :

we 'll define some settings in the upper let
(smile-pos (+ 10 (/ radius 3)))
(smile-radius (* (/ radius 3) 4))
(eye-l-pos-x (+ 10 (/ (* radius 2) 3)))
(eye-r-pos-x (+ 10 (- (+ radius (/ radius 3)) (/ radius 4))))
(eye-pos-y (+ 10 (/ radius 2)))
(eye-radius-x (/ radius 4))
(eye-radius-y (/ radius 3)))

and now create a other selection who REPLACE the older
(gimp-ellipse-select img smile-pos smile-pos smile-radius smile-radius REPLACE TRUE 0 0)

now we want to have a area to stroke in black for the smile, we create a border of size 2
(gimp-selection-border img 2)

and with SUB the upper part of this stroked circle selection
(gimp-rect-select img 10 10 (* radius 2) radius SUB TRUE 0)

and ADD 2 circles for the eyes
(gimp-ellipse-select img eye-l-pos-x eye-pos-y eye-radius-x eye-radius-y ADD TRUE 0 0)
(gimp-ellipse-select img eye-r-pos-x eye-pos-y eye-radius-x eye-radius-y ADD TRUE 0 0)

now we can fill with black the selection :
(gimp-palette-set-foreground '(0 0 0))
(gimp-bucket-fill smile FG-BUCKET-FILL NORMAL-MODE 100 0 FALSE 0 0)))

step 5

now we 'll jump over the selection step of the reflet creation, you just have to now that we'll select a ellipse and now SUB an smaller ellipse to get a "croissant"

we can now fill this "croissant" with white, at intensity 50
(gimp-palette-set-foreground '(255 255 255))
(gimp-bucket-fill reflet FG-BUCKET-FILL NORMAL-MODE 50 0 FALSE 0 0)

and apply a gaussian blur on a img + layer with (here) power 15 15. on :
(plug-in-gauss-iir2 TRUE img reflet 15 15)

now we'll duplicate layer called "reflet" and rotate it to create a second reflet exaclty opposite to this one

we'll put this one on the upper let under the name of 'reflet2'
(reflet2 (car (gimp-layer-copy reflet TRUE)))

add him to image
(gimp-image-add-layer img reflet2 1)

and rotate him by 90°
(gimp-rotate reflet2 TRUE 3.14159)

finished !

step 5

rest to register the script in the data base, with his name, place, and args :


(script-fu-register
"script-fu-smiley"
"<Toolbox>/Xtns/Script-Fu/Button/Smiley"
<--- placed at Xtns -> Script-Fu -> Button -> Smiley
"yellow smiley face"
"MARIN Laetitia"
"MARIN Laetitia"
"Fev 2000"
""
SF-VALUE "Radius" "64")

NB : if you want to register a script applyed to an existant image proceed as follow


(script-fu-register
"script-fu-stamp"
"<Image\>/Script-Fu/Decor/Stamp"
<--- placed at image -> Script-Fu -> Decor -> Stamp
"stamp border imitation"
"MARIN Laetitia"
"MARIN Laetitia"
"Fev 2000"
""
SF-IMAGE "Image to stamp" 0
<--- necessary arg, image treated
SF-DRAWABLE "Drawable to stamp" 0)
<--- necessary arg, layer treated

the necessary arg can be followed by optionnal args and 'll be treated in the same order by the script.
(define (script-fu-stamp img drawable) .....

here is the script.

Points you should remember about script fu:

  1. don't name 2 different func in differents files with the same name if they do not do the same thing, only the last would be kept by interpreter
  2. use emacs with global-font-lock-mode and show-paren-mode fixed at TRUE

    close all the parents (if they are not in enought number then there is some error at gimp-launch time, but if they are misplaced error appear at run time).

    verify that all the var you use in a func are registred somewhere when you use them (error at runtime)

  3. use exts -> scriptfu -> refresh in view to reload scripts
  4. variable names use some '-' and no '_' (NORMAL-MODE by example)
  5. warning, old script use deprecated func
  6. use exts -> browse procédure database to look for func names, args, and out