Gimp “Script-Fu” example (functions, parameters)

I’ve mentioned this before, but if you’re interested in learning Lisp/Scheme programming, the makers of gimphelp.org have a nice collection of plugins for Gimp 2.8 that you can download, and they’re all written in Scheme. (Well, a variation of Scheme.)

Here’s the body of a Gimp plugin file named FU_contrast_auto-contrast.scm:

(define (FU-auto-contrast
        img
        drawable
        merge-flag)

    (gimp-image-undo-group-start img)
    (if (not (= RGB (car (gimp-image-base-type img))))
             (gimp-image-convert-rgb img))   

   ; Create a new layer
   (define value-layer (car (gimp-layer-copy drawable 0)))

   ; Give it a name
   (gimp-item-set-name value-layer "Contrast Adjustment Layer")

   ; Add the new layer to the image
   (gimp-image-insert-layer img value-layer 0 0)

   ; Set opacity to 100%
   (gimp-layer-set-opacity value-layer 100)

   ; Set the layer mode to Value
   (gimp-layer-set-mode value-layer 14)

   ; Adjust contrast
   (gimp-levels-stretch value-layer)

   ; Merge down, if required
   (if (equal? merge-flag TRUE)
       (gimp-image-merge-down img value-layer 1 )
       ()
   )
   (gimp-image-undo-group-end img)
   (gimp-displays-flush)   
)
(script-fu-register "FU-auto-contrast"
    "<Image>/Script-Fu/Contrast/Auto Contrast"
    "Automatically adjust contrast of drawable"
    "Mark Lowry"
    "Mark Lowry"
    "2006"
    "*"
    SF-IMAGE    "Image"         0
    SF-DRAWABLE "Current Layer" 0
    SF-TOGGLE   "Merge Layers?" FALSE
)

If you’re at least a little comfortable with Lisp/Scheme — and also Gimp — that code is relatively easy to understand. For instance, the define function creates a variable named value-layer, and then other Gimp functions like gimp-item-set-name and gimp-image-insert-layer modify value-layer.

At the end of the code, the script-fu-register shows how to register a plugin so that Gimp will find it and display it in the Gimp menu system.

Observations

A few observations come to mind:

1) Like other languages that don’t show their types, you can’t tell value-layer’s type from looking at the code, though you can assume that it’s something like Layer.

2) For some reason Lisp makes it more clear than other languages that you can’t tell what the function parameters are. They’re based on the positions in the list, and seeing "Mark Lowry" in there twice makes you wonder why it’s there twice. The only way to know what the parameters are is (a) guessing by what’s in each field, and (b) looking at the script-fu-register documentation. (This is true in other programming languages, but it really stands out here, possibly because of the formatting.)

Gimp Script-Fu function examples

If you are looking for Gimp Script-Fu function examples (as I was), the Gimp function examples used in this code are:

  • gimp-image-undo-group-start
  • gimp-image-convert-rgb
  • gimp-layer-copy
  • gimp-item-set-name
  • gimp-image-insert-layer
  • gimp-layer-set-opacity
  • gimp-layer-set-mode
  • gimp-levels-stretch
  • gimp-image-merge-down
  • gimp-image-undo-group-end
  • gimp-displays-flush
  • script-fu-register

The complete source code

Here’s the complete source code for this plugin, including the initial comments and license:

; FU_contrast_auto-contrast.scm
; version 2.9 [gimphelp.org]
; last modified/tested by Paul Sherman
; 02/15/2014 on GIMP-2.8.10
;
; 02/15/2014 - convert to RGB if needed
;==============================================================
;
; Installation:
; This script should be placed in the user or system-wide script folder.
;
;    Windows Vista/7/8)
;    C:\Program Files\GIMP 2\share\gimp\2.0\scripts
;    or
;    C:\Users\YOUR-NAME\.gimp-2.8\scripts
;    
;    Windows XP
;    C:\Program Files\GIMP 2\share\gimp\2.0\scripts
;    or
;    C:\Documents and Settings\yourname\.gimp-2.8\scripts   
;    
;    Linux
;    /home/yourname/.gimp-2.8/scripts  
;    or
;    Linux system-wide
;    /usr/share/gimp/2.0/scripts
;
;==============================================================
;
; LICENSE
;
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
;
;==============================================================
; Original information
;
; Automatically adjusts contrast of the current
; drawable by duplicating the layer, setting the
; new layer to Value blend mode, then running
; Auto Levels on the Value layer.
;==============================================================

(define (FU-auto-contrast
        img
        drawable
        merge-flag
    )
    (gimp-image-undo-group-start img)
    (if (not (= RGB (car (gimp-image-base-type img))))
             (gimp-image-convert-rgb img))   

   ; Create a new layer
   (define value-layer (car (gimp-layer-copy drawable 0)))

   ; Give it a name
   (gimp-item-set-name value-layer "Contrast Adjustment Layer")

   ; Add the new layer to the image
   (gimp-image-insert-layer img value-layer 0 0)

   ; Set opacity to 100%
   (gimp-layer-set-opacity value-layer 100)

   ; Set the layer mode to Value
   (gimp-layer-set-mode value-layer 14)

   ; Adjust contrast
   (gimp-levels-stretch value-layer)

   ; Merge down, if required
   (if (equal? merge-flag TRUE)
       (gimp-image-merge-down img value-layer 1 )
       ()
   )
   (gimp-image-undo-group-end img)
   (gimp-displays-flush)   
)
(script-fu-register "FU-auto-contrast"
    "<Image>/Script-Fu/Contrast/Auto Contrast"
    "Automatically adjust contrast of drawable"
    "Mark Lowry"
    "Mark Lowry"
    "2006"
    "*"
    SF-IMAGE     "Image"         0
    SF-DRAWABLE "Current Layer" 0
    SF-TOGGLE     "Merge Layers?" FALSE
)