astrobio has asked for the wisdom of the Perl Monks concerning the following question:

Among the interesting ways to access complex image manipulation routines inside the GIMP--in addition to Gimp::Fu, Imager, or the somewhat bewitching installation of Image::Magick--a batching system can combine perl with scheme calls. This route makes possible rapid code modifications based on what parameters can be customized directly within the GIMP Module database.

What is the preferred perl-only way to get the directory listing of available image types (other than the GNU utility 'du -a | grep jpg')? What would be a recommended templating system to learn from (along the lines of HTML templates), that instead works on the Scheme templates used here in __DATA__ for a more generalized way of proceeding for all the gimp? Any other improvements most welcome.

There is a whole slew of these utilities associated with a project on sourceforge here that I am looking to improve.

Thanks for suggestions.

Example code for creating a jigsaw image:

# Batch process whole directories # jigsaw filter # config path to installed gimp-1.2 $HOME = $ENV{'HOME'}; $home="$HOME/.gimp-1.2/scripts"; $imgtype='jpg'; # format(s) for input/output image types $postcopy='new_'; # prefix on new images use Getopt::Long qw(:config no_ignore_case bundling); $|=1; #! #!<VERSION> my $version="0.2"; my $version_date="09/09/03"; #!</VERSION> #! #Get command line options my $flag_help=0; my $flag_version=0; GetOptions( 'h'=>\$flag_help, 'help'=>\$flag_help, 'v'=>\$flag_version, 'version'=>\$flag_version, ); if ($flag_help) { #List Options print STDOUT "batchgimp is a perl-based, command-line script for a +ccessing the \n". "Gimp Extensions/Plug-ins/Load & Save-Handlers.\n". "To use, copy $0 to the folder where a batch of images resid +e.\n" . " perl $0 \n". " where $0 is the name of the action inside GIMP that is \n". " being batched processed.\n" . " As an example, to add a bevel to a group of images, in fold +er \n". " $HOME/myimages, type \n\n". " cp bevel.pl $HOME/myimages \n". " cd $HOME/myimages \n". " perl bevel.pl \n". " To list the resulting beveled images,\n". " ls -l | grep new_imageroot \n\n"; exit 0; } if ($flag_version) { #Show Version print STDOUT "Batch Gimp - gimp calls on command-line \nfor image +processing directories\n"; print STDOUT "Version number $version\n"; print STDOUT "Latest revision on $version_date\n"; print STDOUT "For more information, see http://freshmeat.net/proje +cts/batchgimp/ \n"; exit 0; } # development $debug=0; # subs get_images(); config(); batch(); quietgimp(); cleanup(); # file list sub get_images { undef @images; $images= `du -a --max-depth=1 | grep $imgtype `; @tmp= split(/\n+/,$images); foreach(@tmp){ chomp; s/^\s+|\s+$//g; s/^.*?\///g; push(@images,$_); print "Working image ... $_\n"; } } # prepare input/output file names sub config { my @chars = ("A".."Z","a".."z",0..9); $randomz = join("",@chars[ map {rand@chars}(1..3) ] ); $batch = $imgtype .'-files' . $randomz . '.scm'; $script = $imgtype .'-file' . $randomz . '.scm'; $function =$imgtype.'-function'; # write header 'define' open(GIMP,">$path/$script") || die "Can't access gimp home directo +ry\n"; print GIMP '(define ('.$imgtype .'-files)' . "\n"; # loop images foreach(@images){ print GIMP "($function ". ' "'.$_ .'" "'.$postcopy.$_.'")'."\n +"; } # write footer print GIMP ')'; } # run sub batch { # # Create the processing script # Cut and paste Scheme to insert below in DATA # @scheme=<DATA>; $scheme=join('',@scheme); $scheme=~s/<!--FUNCTION-->/$function/; print GIMP "\n\n $scheme \n\n"; } # batch syntax to run non-interactively sub quietgimp { # call the gimp quietly my $command = " gimp --no-interface --no-data --batch '(". $imgtyp +e ."-files)' '(gimp-quit 0)' "; if($debug eq 0){ system("$command"); } } # end sub cleanup { close GIMP; if($debug eq 0){ system("rm -f $path/$script"); } } # # cut and paste the scheme script here # only place holder is the function name, my-function __DATA__ (define (<!--FUNCTION--> source-name dest-name ) ; load the image (set! img (car (gimp-file-load 1 source-name source-name))) ; flush the undo buffer to save swap space (gimp-image-undo-disable img) ; flatten the layers to one for jpg (set! drawable (car (gimp-image-flatten img))) ; call the jigsaw plug-in script with parameters (plug-in-jigsaw 1 ; non-interactive img ; image name drawable ; drawable 5 ; X-number of tiles 5 ; Y-number of tiles 1 ; style shape of puzzle 3 ; blend_lines number lines for shading bevels 2 ; blend_amount light power of highlights ) ; save out the jpeg with parameter settings (file-jpeg-save 1 ; non-interactive img ; the input image drawable ; flattened layer drawable to save dest-name ; the output dest-name ; the raw output 0.75 ; quality (0<=quality<=1) 0.00 ; smoothing (0<=smoothing factor<=1) 0 ; optimize (0,1) 0 ; progressive "comment" ; image comment 0 ; subsampling option 1 ; baseline 0 ; restart markers 1 ; DCT algorithm ) ; clean up to redo next image (gimp-image-undo-enable img) )

update (broquaint): added <readmore>

Replies are listed 'Best First'.
Re: Batch Gimp via Scheme Interface
by tachyon (Chancellor) on Sep 09, 2003 at 12:23 UTC
    @jpgs = glob("/path/to/images/*.jpg"); @big_jpgs = grep { -s $_ > 100000 } glob("/images/*.jpg");

    Text::Template and Template::Toolkit are general purpose templating systems. If your requirements are modest you can always just use an RE

    my $template = get_template(); $template =~ s/<%token%>/$token_value/g;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Batch Gimp via Scheme Interface
by Roger (Parson) on Sep 09, 2003 at 11:53 UTC
    Use the opendir in perl to parse directory contents. The following is a code example:

    opendir DIRH, "." or die "Could not open directory."; my @dir = readdir DIRH; closedir DIRH; foreach (@dir) { print "file: $_\n"; }
    Another neat method is to use the File::Find module, which can traverse a nested directory structure. The documentation is on CPAN, so I am not going to give example here.
Re: Batch Gimp via Scheme Interface
by bart (Canon) on Sep 09, 2003 at 12:59 UTC
    For a templating system, I'd first think of Template Toolkit or Text::Template. The former is very powerful, and maybe a bit overwhelming... the latter is simpler, and most likely more than good enough for your purpose.

    There's a comparison of templating systems available in an article on perl.com: "Choosing a templating system". There's another one in the O'Reilly book on Mason: "Alternatives to Mason".

Re: Batch Gimp via Scheme Interface
by astrobio (Beadle) on Sep 09, 2003 at 14:26 UTC
    If a demonstration wanted to run this from cgi, there seem two possible ways, which is complicated only by the fact that GIMP calls its batch stack from a specific path, which is what this writes to with parameters on image location.

    So would it be better, as a test case to:
    a) set a sticky bit on the directory
    .gimp-1.2/scripts
    such that apache's user is able to write to it
    -srwxrwxr-x 1 user apache myscript.scm

    b) just prepare a fixed set of scheme scripts and call them through appropriately protected shell calls within the cgi--like any ofther system utility.

    Thanks for your suggestions.