The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Gimp::ScriptFu::Client - Client for the GNU Image Manipulation Program

SYNOPSIS

Makes a mixed Scheme and Perl script into a client application for the Gimp Script-Fu server.

VERSION

Version 1.01, Feb 6, 2007

DESCRIPTION

Gimp::ScriptFu::Client acts as a source filter in a Scheme script that uses Text::Template to preprocess any embedded Perl fragments contained between { } brackets before sending the resulting Scheme to a Gimp Script-Fu server. Each Perl fragment may or may not produce a Scheme fragment.

The Scheme script becomes a standalone client application.

This permits using Perl for getting parameters from the real world or for generating complex Scheme expressions, that would be more difficult or impossible with plain Scheme.

It also makes it possible to do Perlish things with Gimp if you can't do the compiler stuff for Gimp/Gimp::Fu for your OS. All recent Gimp versions include the Script-Fu server.

Starting the Gimp server

Run Gimp with something like:

    gimp-x.x -b "(plug-in-script-fu-server 1 10008 \"\")"

or start Gimp and start the server from the menu Xtns/Script-Fu/Start Server.

Usage

Include this module at the beginning of the script:

    use Gimp::ScriptFu::Client;

Everything after that is Scheme or embedded Perl fragments.

Command line options for the Client are:

    --server   -s   # alternate server address
    --port     -p   # alternate server port
    --verbose  -v   # display Scheme before sending request
    --check    -c   # generate Scheme for syntax check and exit

Options -v and -c may be bundled as -vc or -cv.

The rest of the file after the use Gimp::ScriptFu::Client line is preprocessed by Text::Template for embedded Perl - anything between curly brackets. Perl variables persist from fragment to fragment in a file. The resulting Scheme is displayed and/or sent to the Gimp Script-Fu server and the result displayed.

The result may be 'Success', an Error message, or a user success message (see the end of demo.pl shown below).

Helper functions

The Client module provides several helper functions that can be used in Perl fragments:

sexp_from_list()

This function takes a Perl list as an argument and returns a string which is a Scheme expression for that list.

set_argv()

This function takes no arguments and returns a string which is a Scheme expression setting the Scheme variable argv to the Perl array @ARGV.

expand_files()

This function takes a Perl list of filenames or file patterns and expands it to a Perl list of filenames with full real pathnames. On a Win32 system , it will convert backslashes to forward slashes for Gimp use. Gimp needs full paths because the server is running in another directory. This function will die if a filename is not found.

include_script()

This function takes the name of another Scheme/Perl Client script plus any arguments for that script. The arguments are passed to that script in @ARGV. The Scheme output of the included script is returned by its Client code and included in the parent script. The original @ARGV in the parent is preserved. Includes may be nested.

The Client command line option --include is used internally as the first argument to the included script.

Example command lines

Using the example Scheme/Perl script demo.pl, shown below:

    demo *.jpg *.raw                        # quietly send Scheme to Gimp
    demo --verbose test.jpg                 # display Scheme and send to Gimp
    demo --check *.jpg *.bmp                # generate Scheme for error messages and quit
    demo -vc *.jpg                          # display Scheme and/or errors and quit
    demo -s 192.168.1.1 -p 10020 some.jpg   # use a different server
    demo                                    # demo uses file dialog to get file names

Client options are processed by Getopt::Long. To pass options to the script use --

    demo --verbose -- --ext=jpg --scale=.5 *jpg   # pass --ext and --scale thru to demo
                                                  #  --verbose eaten by Client

Included scripts have -- prepended to the argument list automatically, since the Client options are only needed for the parent script.

Syntax errors will report line numbers for the template, not the file. The line after use Gimp::ScriptFu::Client; is line 1 of the template.

Example script 'demo.pl'

    #!perl -w
    use Gimp::ScriptFu::Client;
    {use Getopt::Long;
     $ext = 'png';
     $scale = .1;
     GetOptions( "ext=s"   => \$ext,   # thumbnail extension
                 "scale=f" => \$scale, # thumbnail scale
               );

     # This helper function expands all patterns,
     #  adds needed paths and converts Win32 backslashes
     @ARGV = expand_files( @ARGV );
     die "No files selected\n" if !@ARGV;

     # no Scheme output from this Perl fragment
     ''; }

    ; Server only executes one expression per request - use 'begin' wrapper
    (begin (let ( (argv '()) (argc 0) (outfiles '()) (scale 0) )
    ; Gimp >= 2.13.13 is TinyScheme, requires all variables defined before first use

    ; This helper function puts the
    ; contents of @ARGV into the
    ; Scheme variable, argv.
    {set_argv}
    (set! argc {scalar @ARGV})

    ; include another file here
    { include_script('included_script.pl', qw(--mode special a b c)) }
    ; original @ARGV is still = ({ "@ARGV" })

    ; This uses Perl's regexes to create
    ; filenames for the thumbnails.
    (set!
        outfiles '{
            sexp_from_list(
                map { s/\..*$/-thumbnail.$ext/; $_ } @ARGV)})

    ; configure your scaling factor
    (set! scale { $scale })

    ; This is a function for resizing an image
    (define (resize filename)
        (let*
        (
            (image     (car (gimp-file-load 1 filename filename)))
            (drawable  nil)
            (wd        (car (gimp-image-width image)))
            (hi        (car (gimp-image-height image)))
            (_wd       (* wd scale))
            (_hi       (* hi scale))
            (new-filename nil)
        )
        (gimp-image-scale image _wd _hi)
        (set! drawable      (car (gimp-image-flatten image)))
        (set! new-filename  (car outfiles))
        (set! outfiles      (cdr outfiles))
        (gimp-file-save 1 image drawable new-filename new-filename)
        (gimp-image-delete image)
        )
    )

    ; Finally, make a thumbnail out of every file in argv
    (while (car argv)
        (resize (car argv))
        (set! argv (cdr argv))
        )

    ; Use an error message to return a string. If Client receives an error message
    ; starting with "Success\n", that is stripped and the exit status is changed
    ; to zero (no error).
    ; Otherwise, no error returns the string "Success".
    (error  (string-append "Success\nThumbnails created: " (number->string argc)))
    ))

File 'included_script.pl' included in 'demo.pl'

    #!perl -w
    use Gimp::ScriptFu::Client;
    { use Getopt::Long; }
    ; stuff from 'included_script.pl' to test nested 'use' and @ARGV
    ; included @ARGV = ({ "@ARGV" })
    ; mode is { my $mode = 'normal'; GetOptions( "mode=s" => \$mode ); $mode }
    ; after GetOptions, @ARGV = ({ "@ARGV" })

AUTHOR

Alan Stewart <astewart1@cox.net>

BUGS?

Tested with Gimp 2.13.12 and Gimp 2.13.14, compiled with MinGW on Win XP, Perl 5.8.8 Feb 20, 2007

COPYRIGHT

Copyright (c) 2007 Alan Stewart. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

ACKNOWLDGEMENTS

Derived from an article and script by John Beppu <beppu@cpan.org> in Linux Magazine Feb 15, 2002.

SEE ALSO

    Filter::Simple
    Text::Template