187 lines
6.4 KiB
Perl
Executable File
187 lines
6.4 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
# This one's all mine. Well, its GPL/Artisitic but I"m the author and creator. # I think you need gimp 1.1 or better for this - if you don't, please let
|
|
# me know
|
|
|
|
# I'm hacking this on top of my sethspin script, so this is doing even more
|
|
# stuff it wasn't really designed to do. Hence if you thought sethspin was
|
|
# a bit ugly, look at this one...
|
|
|
|
# I think it was tigert that suggested this. It turned out to be less
|
|
# complex than I orginally thought so I figured I'd give it a spin.
|
|
|
|
# Seth Burgess
|
|
# <sjburges@gimp.org>
|
|
|
|
use Gimp qw(:auto);
|
|
use Gimp::Fu;
|
|
use Gimp::Util;
|
|
|
|
# Uncomment below to spew forth much data about whats going on.
|
|
#Gimp::set_trace(TRACE_ALL);
|
|
|
|
sub saw { # a sawtooth function on PI
|
|
($val) = @_;
|
|
if ($val < 3.14159/2.0) {
|
|
return ($val/3.14159) ;
|
|
}
|
|
elsif ($val < 3.14159) {
|
|
return (-1+$val/3.14159);
|
|
}
|
|
elsif ($val < 3.14159+3.14159/2.0) {
|
|
return ($val/3.14159) ;
|
|
}
|
|
else {
|
|
return (-1+$val/3.14159);
|
|
}
|
|
}
|
|
|
|
sub spin_layer { # the function for actually spinning the layer
|
|
my ($img, $spin, $dest, $numframes, $prp, $blinds) = @_;
|
|
# Now lets spin it!
|
|
$stepsize = 3.14159/$numframes; # in radians
|
|
for ($i=0; $i<=3.14159; $i+=$stepsize) {
|
|
Gimp->progress_update ($i/3.14159);
|
|
# create a new layer for spinning
|
|
$framelay = ($i < 3.14159/2.0) ? $spin->copy(1) : $dest->copy(1);
|
|
$img->add_layer($framelay, 0);
|
|
# spin it a step
|
|
# Here I need to make the proper selection, repeatedly if necessary
|
|
$blindheight = $img->height/$blinds;
|
|
for ($j=0; $j<$blinds; $j++) {
|
|
# select a section
|
|
$img->rect_select(0, $j*$blindheight, $img->width, $blindheight, 2, 0, 0.13);
|
|
@x = $img->selection_bounds();
|
|
# x[1],x[2] x[3],x[2]
|
|
# x[1],x[4] x[3],x[4]
|
|
$floater = $framelay->perspective(1,
|
|
$x[1]+saw($i)*$prp*$framelay->width,$x[2]+$blindheight *sin($i)/2,
|
|
$x[3]-saw($i)*$prp*$framelay->width,$x[2]+$blindheight *sin($i)/2,
|
|
$x[1]-saw($i)*$prp*$framelay->width,$x[4]-$blindheight *sin($i)/2,
|
|
$x[3]+saw($i)*$prp*$framelay->width,$x[4]-$blindheight *sin($i)/2);
|
|
|
|
# Gimp Perspective Functionality has changed. It used to create a floating
|
|
# selection if there was a selection active already. Now it only does that
|
|
# in interactive - PDB makes it a new layer. Fine by me, wish the docs had
|
|
# changed though.
|
|
# $floater->floating_sel_anchor;
|
|
|
|
} # end for ($j=0;...
|
|
|
|
# I need to create another layer beind this spun one now
|
|
$backlayer = $framelay->layer_copy(0);
|
|
$img->add_layer($backlayer, 1);
|
|
$backlayer->fill(1); # BG-IMAGE-FILL
|
|
}
|
|
for ($i=0; $i<$numframes; $i++) {
|
|
@all_layers = $img->get_layers();
|
|
$img->set_visible($all_layers[$i],$all_layers[$i+1]);
|
|
$img->merge_visible_layers(0);
|
|
}
|
|
@all_layers = $img->get_layers();
|
|
$destfram = $all_layers[$numframes]->copy(0);
|
|
$img->add_layer($destfram,0);
|
|
|
|
# clean up my temporary layers
|
|
$img->remove_layer($all_layers[$numframes]);
|
|
$img->remove_layer($all_layers[$numframes+1]);
|
|
}
|
|
|
|
register "billboard",
|
|
"Billboard",
|
|
"Take one image. Spin it about the multiple axes, and end up with another image. I made it for easy web buttons, mostly because somebody suggested to me.",
|
|
"Seth Burgess",
|
|
"Seth Burgess <sjburges\@gimp.org>",
|
|
"1.3",
|
|
N_"<Toolbox>/Xtns/Animation/Billboard",
|
|
"*",
|
|
[
|
|
[PF_DRAWABLE, "source", "What drawable to spin from?"],
|
|
[PF_DRAWABLE, "destination","What drawable to spin to?"],
|
|
[PF_INT8, "frames", "How many frames to use?", 16],
|
|
[PF_COLOR, "background", "What color to use for background if not transparent", [0,0,0]],
|
|
[PF_SLIDER, "perspective", "How much perspective effect to get", 40, [0,255,5]],
|
|
[PF_TOGGLE, "spin_back", "Also spin back?" , 0],
|
|
[PF_TOGGLE, "convert_indexed", "Convert to indexed?", 1],
|
|
[PF_SPINNER, "billboard_slats", "Number of shades", 3, [1,50,1]],
|
|
],
|
|
[],
|
|
['gimp-1.1'],
|
|
sub {
|
|
my($src,$dest,$frames,$color,$psp,$spinback,$indexed, $shadenum) =@_;
|
|
$maxwide = ($src->width > $dest->width) ? $src->width : $dest->width;
|
|
$maxhigh = ($src->height > $dest->height) ? $src->height: $dest->height;
|
|
$img = gimp_image_new($maxwide, $maxhigh, RGB);
|
|
|
|
|
|
$tmpimglayer = $img->add_new_layer(0,3,1);
|
|
$img->display_new;
|
|
Gimp->progress_init("Billboard...",-1);
|
|
$oldbackground = gimp_palette_get_background();
|
|
Palette->set_background($color);
|
|
$src->edit_copy();
|
|
$spinlayer = $tmpimglayer->edit_paste(1);
|
|
$spinlayer->floating_sel_to_layer();
|
|
|
|
$dest->edit_copy();
|
|
$destlayer = $tmpimglayer->edit_paste(1);
|
|
$destlayer->floating_sel_to_layer();
|
|
|
|
$tmpimglayer->remove_layer;
|
|
|
|
$spinlayer->resize($maxwide, $maxhigh, $spinlayer->offsets);
|
|
$destlayer->resize($maxwide, $maxhigh, $destlayer->offsets);
|
|
# work around for PF_SLIDER when < 1
|
|
$psp = $psp/255.0;
|
|
|
|
# need an even number of frames for spinback
|
|
if ($frames%2 && $spinback) {
|
|
$frames++;
|
|
gimp_message("An even number of frames is needed for spin back.\nAdjusted frames up to $frames");
|
|
}
|
|
|
|
spin_layer($img, $spinlayer, $destlayer, $spinback ? $frames/2 : $frames-1, $psp, $shadenum);
|
|
$img->set_visible($img->add_new_layer(1),($img->get_layers)[0]);
|
|
$img->merge_visible_layers(0);
|
|
|
|
if ($spinback) {
|
|
@layerlist = $img->get_layers();
|
|
$img->add_layer($layerlist[$frames/2]->copy(0),0);
|
|
@layerlist = $img->get_layers();
|
|
spin_layer($img, $layerlist[1], $layerlist[0], $frames/2, $psp, $shadenum);
|
|
$img->remove_layer(($img->get_layers)[0]);
|
|
}
|
|
|
|
# unhide and name layers
|
|
@all_layers = $img->get_layers;
|
|
$img->set_visible(@all_layers);
|
|
for ($i=1; $i<=$frames ; $i++) {
|
|
$all_layers[$i-1]->set_name("Spin Layer $i (50ms)");
|
|
}
|
|
$all_layers[$frames-1]->set_name("Spin Layer SRC (250ms)");
|
|
|
|
if ($spinback) {
|
|
$all_layers[$frames/2-1]->set_name("Spin Layer DEST (250ms)");
|
|
}
|
|
else { $all_layers[0]->set_name("Spin Layer DEST (250ms)")}
|
|
|
|
|
|
# indexed conversion wants a display for some reason
|
|
if ($indexed) {
|
|
$img->convert_indexed(1, # dither type = fs
|
|
MAKE_PALETTE, # palette type
|
|
255, # number of colors
|
|
0, # don't dither transparency
|
|
1, # (ignored)
|
|
"Custom" # custom palette name
|
|
);
|
|
}
|
|
|
|
Palette->set_background($oldbackground);
|
|
gimp_displays_flush();
|
|
return();
|
|
};
|
|
|
|
exit main;
|
|
|