#!/opt/bin/perl use Gimp qw(:auto __ N_); use Gimp::Fu; register "layer_apply", "Apply a perl expression to every layer of the image", "See POD documentation for detailed help.", "Marc Lehmann ", "Marc Lehmann ", "19990708", N_"/Filters/Generic/Apply Perl Expression...", "*", [ [PF_TEXT, "expr", "the perl expression to run for each layer", '$d->gauss_rle($P*100+1,1,1)'], [PF_DRAWABLE, "drawable2", "an optional extra drawable for use by the code"], ], [], ['gimp-1.1'], sub { my($image,$_drawable,$function,$d2) = @_; my($d,$i,$I,$n,$p,$P); my @layers = $image->get_layers; $n = @layers; $n or die "at least one layer is required\n"; my $func = eval "sub{\n#line 0 \"expression\"\n$function\n}"; die "syntax error in expression '$function': $@\n" if $@; # now apply the function eval { $image->undo_group_start }; # 5.004 has problems with overlaying functions Gimp->progress_init("Applying Expression...",-1); for my $index (0..$n-1) { $i = $index; $I = $n-$i-1; $p = @layers > 1 ? $i/$#layers : 0; $P = 1-$p; $d = $layers[$i]; eval { &$func }; die "evaluation error in frame $i: $@\n" if $@; Gimp->progress_update(($i+1)/$n); } Gimp->displays_flush; eval { $image->undo_group_end }; }; exit main; =head1 DESCRIPTION This function runs a perl expression for each layer of an image. The perl expression can use the following variables: =over 4 =item $image The image. =item $d ("drawable") The current drawable (currently always a layer). =item $i, $I ("index") The index of the current layer. C<$i> counts from 0 to $n-1, i.e. from top to the bottom of the stack with layer #0 being the top of the stack. C<$I> counts "backwards", i.e. from $n-1 to 0, so layer 0 is at the bottom. =item $p, $P ("percent") Similar to $i, but counts from 0 to 1 (inclusive). $p is equivalent to C<$i/($n-1)> and $P is equivalent to C<$I/($n-1)>. =item $n ("number of frames") The number of layers in the image. =item $d2 ("drawable") The drawable2 argument, entirely optional and can be used for anthing you like. =back =head2 EXAMPLES The following expression will gradually fade out an animation. $d->brightness_contrast ($P * 127, 0); This little script can be used to merge two animations, $d2 should point to another animation with the same number of frames (only the image is of concern). It does it by copying each frame of the other animation onto the corresponding frame in the current animation and using DARKEN_MODE to combine the frames. You might want to use other modes or maybe C<$f->set_opacity(50)> for your animation. $i2=$d2->get_image; $l2=($i2->get_layers)[$i]; $i2->selection_all; $l2->edit_copy; $f=$d->edit_paste(0); $f->set_mode(DARKEN_ONLY_MODE); $f->anchor; =head1 LICENSE Copyright Marc Lehman Distrubuted under the same terms as Gimp-Perl. =cut