Notes on GIMP Scripting
Languages:
C, Script-fu, Python: first-class citizensPerl, C++, C#, Ruby: need to find and build a module; not well supported.
Python
Registration:
Help strings: first is short, second is long.
Names: first is script author, second is copyright owner.
Leave output parameters blank, []
Remember to call main() at the end of your Python script.
Image type examples:
- ""
- Create a new image -- don't run from an existing one
- *
- Accept any type of image
- RGB
- RGB only, no alpha channel (no transparency)
- RGBA
- Only RGB with transparency
- RGB*
- RGB with or without transparency
- GRAY
- Only grayscale, no transparency
- GRAY*
- Grayscale with or without transparency
- INDEXED
- Only indexed, no transparency
- RGBA,GRAY*,INDEXED
- Accept RGB with transparency, Grayscale with or without, and Indexed only without transparency.
Input parameters:
For a complete list, see the pyui.py example code.
When writing a plug-in that operates on an image, the first two input parameters should be:
(PF_IMAGE, "image", "Input image", None), (PF_DRAWABLE, "drawable", "Input layer", None),and your function definition should take img and layer as its first two arguments.
For functions that create a new image, you don't need image and drawable.
Installing a Python script:
Use Preferences, Folders->Plug-ins to find location of plug-ins on your system. You'll see two: one is the system location (may be overwritten when you reinstall GIMP), one is your personal plug-ins folder.
On Linux it's ~/.gimp-2.6/plug-ins/
Don't forget to make it executable: chmod +x ~/.gimp-2.6/plug-ins/helloworld.py
Must restart GIMP when you add a script or change register()
.
No need to restart when changing other parts of the script --
it runs as a separate process and will be re-read from disk each time.
Custom dialogs:
Can use anything from pygtk.
See ratio_info.py or life.py for examples.
Direct pixel access:
Read pixels with tiles or pixel regions.
Write pixels with pixel regions.
Examples:
- whirlpinch.py (tiles and pixel regions)
- arclayer.py (pixel regions only)
Debugging:
To see output of print, run from a terminal, or tail -f ~/.xsession-errors
Python debuggers work if you can attach to the process -- plug-ins run in their own process.
Python console:
Filters->Python-Fu->Console...
dir(gimp) dir(gimp.Image) >>> gimp.image_list() [<gimp.Image 'img_1444.jpg'>, <gimp.Image 'sea-nettle2.jpg'>] >>> img = gimp.image_list()[1] >>> dir(img) (lots of output) >>> layer = img.active_layer >>> layer.width 1024
Python-Fu documentation:
Documentation on the basic GIMP Python objects, like gimp, pdb, Image, Layer, Drawable: gimp.org/docs/python
Look up PDB functions in GIMP's Procedure Browser, Help->Procedure Browser
Procedure Browser to Python:
- Change dashes to underscores
- Omit any run-mode parameter
- Change -1 to None
Script-Fu
Based on Tiny Scheme.
Use the Tiny-Fu Migration Guide (from scripts written for GIMP 2.2 and earlier) -- which also points to best practices in script-fu development.
Installing script-fu:
Install to ~/.gimp-2.6/scripts/ -- or whatever Preferences says for Folders->Scripts
Then: Filters->Script-Fu->Refresh Scripts
Must Refresh Scripts every time you change a script-fu.
Defining variables:
(let* ( (var1 val) (var2 val) ... ) (statement1) (statement2) ... )
You can also use let
(without the *) -- difference is that
let* lets you refer to var1's value in var2 def, etc. When in doubt
just use let*.
Lisp syntax:
car gives the first element of a list:
> (car '(one two three (a b c) four five)) one
cdr gives the rest of the list, e.g. (two three (a b c) four five)
(if (= (car (gimp-selection-is-empty img)) FALSE) (do-stuff-to-selection) (gimp-message "Nothing is selected") )Always use car: all script-fu functions return a list:
> (gimp-selection-is-empty img) (FALSE)
Group statements with begin:
(if (= (car (gimp-selection-is-empty img)) FALSE) (begin (do-something) (do-something-else) (gimp-progress-update percent-done) ) ;; end "if selection empty" (gimp-message "Nothing is selected") ;; !empty )
Loops: use set! to update a variable you've already declared with let*:
(while (<= y height) (do-stuff) (do-more-stuff) (set! y (+ y 1)) )
Common Tiny-Fu errors (watch out for these!):
Script-Fu Debugging:
(gimp-message (string-append "Width is: " (number->string width)))or, sadly, binary search: delete half the file and see if the error goes away.
Script-fu console:
> (gimp-image-list) (5 #( 9 8 7 3 1 )) > (define img2 (aref (cadr (gimp-image-list)) 1)) img2 > (define layer (car (gimp-image-get-active-layer img2))) layer > (gimp-drawable-width layer) (512) > (gimp-image-width 3) (688)
Script-Fu Documentation:
Look up PDB functions in GIMP's Procedure Browser, Help->Procedure Browser
Finding sample scripts:
GIMP source -- including the online git tree:
and
or google gimp script
or gimp plug-in