This is a little illustration about using / patching Gimp::Fu to make animated gifs, intended to follow on from Dov's tutorial. Please note that I know nothing about any of this stuff whatsoever; the most rudimentary of rudimentary perl knowledge, 2 days experience of Gimp::Fu, and the audacity to wade right in and hack everything with abandon are all I have to offer. But then, if I can get somewhere with this paltry knowledge, then so, in all probability, can you.
The tutorial also takes in batch processing the files, enabling you to, for example, use a script to automatically generate headers for a website.
This document describes a small perl plug-in called slider, which does this:
Ok, so the effect is something less than breathtaking - and it makes big cumbersome gifs as well. But hey, you can
always go and roll your own if you don't like it.
As an introduction to the plugin, I'll show you the command line used to generate that example:
slider -o "GIF-F+L-D50:bl.gif" -text "sliding text" -font "-eraman-haettenschweiler-medium-r-normal-*-26-240-*-*-*-*-*-*"
-fg_color "#00df00" -bg_color "#ffffff" -frames 15
Here's what it all means, blow by blow:
This stuff was done with Gimp 1.1.13, Perl version 5.005_03, and Gimp-perl 1.16. Gimp-Perl lives here; much kudos to Marc Lehmann for it..
Sections: New options in Gimp::Fu::save_image slider source Batching perl-fu Fu.pm patch
As mentioned in Dov's tutorial, you can specify various options when saving files using Gimp::Fu - for example, executing 'basic-logo -o "JPG-Q100:bl.jpg"' specifies that we want a jpg saved at quality 100. These options are described in the Gimp::Fu manpage. To make it easier to work with animated gifs, I've added a few options to the function. The details are below; for now, note that perldoc Gimp::Fu on my system includes
IMAGETYPE is one of GIF, JPG, JPEG, PNM or PNG, options include options valid for all images +F flatten the image (default depends on the image) -F do not flatten the image options for GIF and PNG images +I do save as interlaced (GIF only) -I do not save as interlaced (default) options for GIF animations (use with -F) +L save as looping animation -L save as non-looping animation (default) -Dn default frame delay (default is 0) -Pn frame disposal method: 0=don't care, 1 = combine, 2 = replace options for PNG images -Cn use compression level n options for JPEG images -Qn use quality "n" to save file (JPEG only) -S do not smooth (default) +S smooth before saving |
slider -o "GIF-F+L-D20:bl.gif" -text "Help!!"
Of course, hacking Fu.pm is unwise for the unenlightened; these changes work for me, but always keep a backup, yadda yadda yadda. And it's perfectly possible to generate animated gifs without these modifications, but I think they're handy.
You can download slider here. Of course, it won't be much use until you deface your Fu.pm.
Here's what slider --help
gets you:
Usage: ./slider [gimp-args..] [interface-args..] [script-args..]
gimp-arguments are
-gimp used internally only
-h | -help | --help | -? print some help
-v | --verbose be more verbose in what you do
--host|--tcp HOST[:PORT] connect to HOST (optionally using PORT)
(for more info, see Gimp::Net(3))
interface-arguments are
-o | --output write image to disk, don't display
-i | --interact let the user edit the values first
script-arguments are
-font XLFD font [-*-desdemona-*-*-*-*-*-190-*-*-*-*-*-*]
-border integer border [10]
-text string text [Hello world!]
-bg_color colour Background color [ARRAY(0x8227d6c)]
-fg_color colour Foreground color [ARRAY(0x8227df0)]
-antialias integer 0=Don't antialias, 1= do [1]
-frames integer Number of frames [20]
-stepsize integer Pixels per frame [5]
-delay integer Wait on last frame [1000]
-transparent integer Tranparent background (0=no, 1=yes) [0]
Sometimes you've to combine script options with output options to get the effect you want. To get transparent
backgrounds, for example, you'd issue a command like:
slider -o "GIF-F+L-D20-P2:bl.gif" -text "sliding text" -transparent 1 -antialias 0
The -P2 option (replace frames rather than combining them) is vital for transparent text. Also, the text looks better without
antialiasing.
The code is mostly commented; feel free to mail me any queries, suggestions etc. You can see that we specify the delay
only for the layer called background - the one which displays the text in readable form. All the others take the deafult
delay, as specified in your -o
argument.
|
Ordinarily, calling a script in batch mode entails starting up the gimp for each file. This slows everything down far too much to be
practical if you're working with lots of files. However, using the perl server, we can run the gimp once, in the background, as a server;
the scripts will then connect to the server instance of the gimp instead of creating their own. The bash command I use to do this is:
gimp -n -b '(extension-perl-server 1 0 0)' >&/dev/null &
Note that all output is thrown away here; when debugging things, you might be better off ommitting '>&/dev/null'.
The magic part is that the Gimp::Fu scripts automatically detect the server and talk to it. You just run them from the command
line as normal. To kill the server when you're done processing scripts, execute
kill %"gimp -n"
(again, that's a bash command). This works by matching 'gimp -n' against the command lines of currently running background
jobs; do a 'man bash' for more details.
The command I ran was
diff -C 2 /mnt/new/src/gimp-1.1.13/plug-ins/perl/Gimp/Fu.pm /usr/lib/perl5/site_perl/5.005/i386-linux/Gimp/Fu.pm
You can grab it here. You could then conceivably issue patch Fu.pm < animatedgif.patch
,
but you'd have to be a wild impetuous fool to do anything like that.
*** /mnt/new/src/gimp-1.1.13/plug-ins/perl/Gimp/Fu.pm Wed Nov 17 21:15:08 1999
--- /usr/lib/perl5/site_perl/5.005/i386-linux/Gimp/Fu.pm Mon Nov 29 02:32:28 1999
***************
*** 798,801 ****
--- 798,807 ----
-I do not save as interlaced (default)
+ options for GIF animations (use with -F)
+ +L save as looping animation
+ -L save as non-looping animation (default)
+ -Dn default frame delay (default is 0)
+ -Pn frame disposal method: 0=don't care, 1 = combine, 2 = replace
+
options for PNG images
-Cn use compression level n
***************
*** 820,824 ****
sub save_image($$) {
my($img,$path)=@_;
! my($interlace,$flatten,$quality,$type,$smooth,$compress);
$interlace=0;
--- 826,830 ----
sub save_image($$) {
my($img,$path)=@_;
! my($interlace,$flatten,$quality,$type,$smooth,$compress,$loop,$dispose);
$interlace=0;
***************
*** 826,829 ****
--- 832,838 ----
$smooth=0;
$compress=7;
+ $loop=0;
+ $delay=0;
+ $dispose=0;
$_=$path=~s/^([^:]+):// ? $1 : "";
***************
*** 836,839 ****
--- 845,851 ----
$quality=$1*0.01, next if s/^-[qQ](\d+)//;
$compress=$1, next if s/^-[cC](\d+)//;
+ $loop=$1 eq "+", next if s/^([-+])[lL]//;
+ $delay=$1, next if s/^-[dD](\d+)//;
+ $dispose=$1, next if s/^-[pP](\d+)//;
croak __"$_: unknown/illegal file-save option";
}
***************
*** 849,857 ****
$layer->file_jpeg_save($path,$path,$quality,$smooth,1,$interlace,"",0,1,0,0) if $@;
} elsif ($type eq "GIF") {
! unless ($layer->indexed) {
eval { $img->convert_indexed(1,256) };
$img->convert_indexed(2,&Gimp::MAKE_PALETTE,256,1,1,"") if $@;
}
! $layer->file_gif_save($path,$path,$interlace,0,0,0);
} elsif ($type eq "PNG") {
$layer->file_png_save($path,$path,$interlace,$compress);
--- 861,869 ----
$layer->file_jpeg_save($path,$path,$quality,$smooth,1,$interlace,"",0,1,0,0) if $@;
} elsif ($type eq "GIF") {
! unless (Gimp::gimp_drawable_is_indexed($layer)) { # HD: changed from ($layer->indexed) {
eval { $img->convert_indexed(1,256) };
$img->convert_indexed(2,&Gimp::MAKE_PALETTE,256,1,1,"") if $@;
}
! $layer->file_gif_save($path,$path,$interlace,$loop,$delay,$dispose);
} elsif ($type eq "PNG") {
$layer->file_png_save($path,$path,$interlace,$compress);