#!perl -w
use strict;
use Imager;
use POSIX qw(ceil);
$Imager::formats{gif} || $Imager::formats{ungif}
or die "Your build of Imager doesn't support gif\n";
$Imager::formats{gif}
or warn "Your build of Imager output's uncompressed GIFs, install libgif instead of libungif (the patents have expired)";
my $factor = shift;
my $in_name = shift;
my $out_name = shift
or die "Usage: $0 scalefactor input.gif output.gif\n";
$factor > 0
or die "scalefactor must be positive\n";
my @in = Imager->read_multi(file => $in_name)
or die "Cannot read image file: ", Imager->errstr, "\n";
# the sizes need to be based on the screen size of the image, but
# that's only present in GIF, make sure the image was read as gif
$in[0]->tags(name => 'i_format') eq 'gif'
or die "File $in_name is not a GIF image\n";
my $src_screen_width = $in[0]->tags(name => 'gif_screen_width');
my $src_screen_height = $in[0]->tags(name => 'gif_screen_height');
my $out_screen_width = ceil($src_screen_width * $factor);
my $out_screen_height = ceil($src_screen_height * $factor);
my @out;
for my $in (@in) {
my $scaled = $in->scale(scalefactor => $factor, qtype=>'mixing');
# roughly preserve the relative position
$scaled->settag(name => 'gif_left',
value => $factor * $in->tags(name => 'gif_left'));
$scaled->settag(name => 'gif_top',
value => $factor * $in->tags(name => 'gif_top'));
$scaled->settag(name => 'gif_screen_width', value => $out_screen_width);
$scaled->settag(name => 'gif_screen_height', value => $out_screen_height);
# set some other tags from the source
for my $tag (qw/gif_delay gif_user_input gif_loop gif_disposal/) {
$scaled->settag(name => $tag, value => $in->tags(name => $tag));
}
if ($in->tags(name => 'gif_local_map')) {
$scaled->settag(name => 'gif_local_map', value => 1);
}
push @out, $scaled;
}
Imager->write_multi({ file => $out_name }, @out)
or die "Cannot save $out_name: ", Imager->errstr, "\n";
=head1 NAME
=for stopwords gifscale.pl
gifscale.pl - demonstrates adjusting tags when scaling a GIF image
=head1 SYNOPSIS
perl gifscale.pl scalefactor input.gif output.gif
=head1 DESCRIPTION
Scales an input multiple-image GIF file. Unlike a simple scale each file
solution this:
=over
=item *
preserves GIF animation attributes
=item *
adjusts the sub-images positions on the background accounting for the
scale factor.
=back
=head1 AUTHOR
Tony Cook <tonyc@cpan.org>
=cut