This page is dedicated to The GNU Image Manipulation Program (a.k.a. The GIMP). Here you can find some scripts and some discussion on my findings.
Here's a collection of scripts providing very basic functionality which was missing from the GIMP at the time they were written.
numeric-ops.scm - Script that allows performing several operations by numeric entry of the parameters (positions, offsets, etc.) (Updated: 2009-03-18, to fix bug preventing it from working on GIMP 2.4.)
Here's a list of the operations numeric-ops.scm supports:
- Place horizontal/vertical guide given its coordinate.
- Set the layer's position to the given coordinates.
- Displace the current layer by the given amount.
- Displace the current selection by the given amount.
- Select a rectangle given its left, top, right and bottom.
- Select an ellipse given its bounds.
- Create an elliptic path given its bounds.
- Create a rectangular path given its corners.
- Create a diamond-shaped path given its bounds.
All of them are placed in the Script-fu/Numeric submenu under
the image's context menu. If you have a suggestion for an option not
included here, feel free to email me to the address below.
center-ops.scm - This script allows centering of the selection and a layer with
respect to either the image or another layer. All of them are installed
under the image's context menu.
The selection operations are placed in the Script-fu/Selection submenu;
the layer operations are placed in the Script-fu/Layer submenu.
If you have a suggestion for an option not included here,
feel free to email me to the address below.
show-bounds.scm - Shows the selection boundaries in a popup window (or the image's boundaries in the case that there's no active selection). Registered in "<Image>/Script-fu/Selection/Show Selection Bounds".
change-brush.scm - This script contains two utility functions that change to the previous/next brush. They register into the image's submenu Script-fu/Utils/Keyboard-triggered with the intention that you assign keyboard shortcuts to them. Suggested by lukashi on IRC.
select-layer.scm - This is a simple tool that selects the current layer as opposed to the whole image. It's useful e.g. to use Round Selection on the current layer's extents (that's what I needed it for). This one is registered in the Select submenu of the image's context menu, in an option called "Current Layer".
It's a well known fact that it's not possible in Script-Fu to declare local functions shared by several global functions so that no namespace pollution occurs. The ancillary functions declared in a file are visible from another file and sometimes this causes trouble when functions with the same name are overwritten.
I've said it's not possible... or is it?
Well, the Scheme language actually provides a mechanism which makes this possible. Even if SIOD, the interpreter in which Script-Fu is based, lacks some of the standard Scheme features, that turns out not to be a problem in this case.
In Scheme, the "set!" construction allows to bind
values to variables which are at a scope level higher than the
current one so that these values are visible outside the current
scope. On the other hand, the function registering mechanism of
Script-Fu requires a function to be declared in the top level of
scope for it to be visible to The GIMP. Another important point to
note is that in Scheme a variable's value can be a function body;
indeed all functions are actually variables whose value is their
body. When we take all these facts into account, we are ready to
use locally defined functions.
The idea is: the whole file is enclosed within an empty
"let" or "let*" except for the initial
bindings of the global functions (variables) to dummy values. Then,
within the "let" we can use locally defined functions
and variables at will and we use "set!" to bind the
global functions to their definitions. Here's an example to better
understand this idea:
; Declare the global variable which will hold the function.
(define script-fu-do-something 0)
; Enter local scope.
(let ()
; Sample local function A.
(define (local-function-a param1 param2)
body)
; Sample local function B.
(define (local-function-b param1 param2)
body)
; Assign the body of the function to the global variable.
(set! script-fu-do-something
(lambda (param1 param2)
body))
; Register the global variable, which is now a function.
(script-fu-register "script-fu-do-something"
...))
Alternatively and perhaps in a clearer fashion, we can define a local function and assign it to the global variable, like this:
; Declare the global variable which will hold the function.
(define script-fu-do-something 0)
; Enter local scope.
(let ()
; Sample local function A.
(define (local-function-a param1 param2)
body)
; Sample local function B.
(define (local-function-b param1 param2)
body)
; Define the global function as a local one.
(define (do-something param1 param2)
body)
; Export the local function to the global variable.
(set! script-fu-do-something do-something)
; Register the global variable, which is now a function.
(script-fu-register "script-fu-do-something"
...))
It's not important whether the script-fu-register call
is inside or outside the let.
In Scheme it's mandatory that the variables are defined before their
value is changed with "set!". SIOD does not require this
but it's highly recommended to follow that convention so that if the
GIMP's Scheme interpreter ever changes (which is very likely), the
script remains valid. [UPDATE: as of GIMP 2.4 that has happened:
SIOD has been replaced with TinyScheme which has that restriction on
the set! function.]
There's an example of this construction in numeric-ops.scm above.
Since version 1.3, the functions
script-fu-numeric-rect-select and
script-fu-numeric-ellipse-select share a common locally
defined function, map-op.
There have been previous unsuccessful attempts at solving this problem, e.g. Lasm's attempt (as it can be discovered later in that thread, that attempt was bogus). The one presented here has been carefully tested and found to work perfectly even after restarting the GIMP. What is local remains local whilst the global functions can still be called and work flawlessly. The local functions' names are not visible to the rest of The GIMP, just as expected.
Use this address to send me E-mail: parigalo@formauri.es.
NOTE: THIS ADDRESS IS NOT PERMANENT.
Always verify this page to send me E-mail because it's likely to change often
for spam reasons.
Any kind of suggestions are welcome.
© Copyright 1998,1999,2000,2002,2003,2004,2005 Pedro Gimeno Fortea. All rights reserved.
This is valid XHTML 1.0.