size=5> Next Previous Contents

4. Use of Script-fu in batch mode.

Generally, batch mode is simply used as a way to run a pre-written Script-fu script. The problem is that to work properly with the current batch mode implementation, the scripts have to be modified first.

4.1 Replace the '-' with '_' in the PDB name.

The first thing that needs to be done is to change the main define of the script so thats its name is of the form (script_fu_test_script) instead of (script-fu-test-script). There's not really a good explanation of why this is neccasary, but its caused by weird interactions between the batch mode parser and the scheme parser thats part of Script-Fu. For example, take a look at swirly-pattern.scm, a script by Frederico Mena Quintero that is provided with the standard gimp distribution. You first need to change the registered name of the script, in this case "script-fu-swirly-pattern". For batch mode to work, the '-' need to be replaced with '_' (replace the dashes with underscores). So change "script-fu-swirly-pattern" to "script_fu_swirly_pattern".

This just changes the registered name of the script, you also need to change the main define of the script to the new name. In swirly-tile.scm, this is line 23:

        (define (script-fu-swirly-pattern qsize angle times)
           (define (whirl-it img drawable angle times)
                   (if (> times 0)
                    ....

which needs to be changed to:

        (define (script_fu_swirly_pattern qsize angle times)
           (define (whirl-it img drawable angle times)
             (if (> times 0)

Only the main define needs to be changed. All the other defines and variables names cab remain the same. This is because the main define is the only one registered in the PDB.

4.2 Remove any UI dependent procedures from the script.

This is primarily intended for scripts that are designed to be run without a ui from the commandline. If you intend to run the script in batch mode with the ui, there is no need to go though this step.

You need to edit scripts so that they do not depend on any thing that might require the user interface. Typically, this means calls to (gimp-display-new). This function is the function that creates a display window for any image that has been created in the script. Other calls to look for include (gimp-displays-flush) and (gimp-display-delete).

It is also important that all plugins or procedures run in non-interactive mode so that they don't spawn dialogs. This shouldn't be a problem with any of the scripts in the main gimp distribution, but it is something to watch for. For plugins, being called with 0 as the first argument is the interactive mode. Make sure all plugins in your scripts are launched with 1 as the first parameter to make sure they launch non-interactively.

4.3 Saving the images

Most scripts just create an image, display it, and wait for the user to delete it, modify it, or save it. In interactive mode, this wont work of course. The scripts generally have to be modified to save the images. Depending on your needs, this may require just adding a call to (gimp-file-save) with the proper parameters, or it may be somewhat more involved.

You should be able to make the script return the image id and drawable id and then have batch mode save it. But most existing scripts do not do this, so the point is a bit moot. To use an existing script-fu, more than likely the script is going to need to be modified to save the image. This is not a trivial thing to do though.

Multi-layered images, for example, will need to be flattened before it can be saved to most formats. Images destined for web pages may need to be indexed if they are to be saved as gif's. The user may also want to be able to pass the filename on the command line.

The following is an example of swirly-pattern.scm modified to allow the user to run it in batch mode and to specify the filename to save the image as.

/* FIXME FIXME */ This is a script for gimp 1.1 script-fu, 1.0 requires more paranoid escaping of quotes and apostrophes.


(define (script_fu_swirly_pattern qsize angle times filename)
  (define (whirl-it img drawable angle times)
    (if (> times 0)
        (begin
          (plug-in-whirl-pinch 1 img drawable angle 0.0 1.0)
          (whirl-it img drawable angle (- times 1)))))

  (let* ((hsize (* qsize 2))
         (img-size (* qsize 4))
         (img (car (gimp-image-new img-size img-size RGB)))
         (drawable (car (gimp-layer-new img img-size img-size RGB "Swirly pattern" 100 NORMAL)))

         ; Save old foreground and background colors

         (old-fg-color (car (gimp-palette-get-foreground)))
         (old-bg-color (car (gimp-palette-get-background))))

    (gimp-image-disable-undo img)
    (gimp-image-add-layer img drawable 0)

    ; Render checkerboard

    (gimp-palette-set-foreground '(0 0 0))
    (gimp-palette-set-background '(255 255 255))

    (plug-in-checkerboard 1 img drawable 0 qsize)

    ; Whirl upper left

    (gimp-rect-select img 0 0 hsize hsize REPLACE 0 0)
    (whirl-it img drawable angle times)
    (gimp-invert img drawable)

    ; Whirl upper right

    (gimp-rect-select img hsize 0 hsize hsize REPLACE 0 0)
    (whirl-it img drawable (- angle) times)

    ; Whirl lower left

    (gimp-rect-select img 0 hsize hsize hsize REPLACE 0 0)
    (whirl-it img drawable (- angle) times)

    ; Whirl lower right

    (gimp-rect-select img hsize hsize hsize hsize REPLACE 0 0)
    (whirl-it img drawable angle times)
    (gimp-invert img drawable)

    ; Terminate

    (gimp-selection-none img)
    (gimp-palette-set-foreground old-fg-color)
    (gimp-palette-set-background old-bg-color)
    (gimp-image-enable-undo img)
; this has to be comment out or removed for non-gui use
;    (gimp-display-new img)

; this will save the filename in the directory from which gimp was launched
    (gimp-file-save 1 img drawable filename filename)
))

(script-fu-register "script_fu_swirly_pattern"
                    "<Toolbox>/Xtns/Script-Fu/Patterns/Swirly (tileable)"
                    "Create a swirly pattern"
                    "Federico Mena Quintero"
                    "Federico Mena Quintero"
                    "June 1997"
                    ""
                    SF-ADJUSTMENT "Quarter size" '(20 0 2048 1 10 0 1)
                    SF-ADJUSTMENT "Whirl Angle" '(90 0 360 1 1 0 0)
                    SF-ADJUSTMENT "Numer of times to whirl" '(4 0 128 1 1 0 1)
                    SF-STRING  "Filename" "swirly.jpg")

In cases where a multi-layer image is created, it may be neccasary to add a call to (gimp-image-flatten) or (gimp-image-merge-visible-layers). The thing to keep in mind here is that the file save commands need the id of the resulting drawable from the merging, so it is neccasary to get it. For example:

        (set! layer-to-save (gimp-image-merge-visible-layers img 0))
        (gimp-file-save 1 img layer-to-save filename filename)

When specifying filenames and file types to save as, bear in mind that gifs must be indexed first, jpegs can not have transparency, and png's and jpg's cant be multi-layer.

For an example of how to merge and index an image in preparation for saving, take a look at the gimp.org scripts in gimp-headers.scm.


Next Previous Contents