use strict;
use warnings;
use feature 'say';
use Imager;
use MCE::Loop;
use Time::HiRes 'time';
use GD;
STDOUT->autoflush;
my $start = time;
my $count = 0;
my @data;
my $bkg;
my $TEST_GD = $ARGV[ 0 ] // 1;
MCE::Loop->init(
max_workers => MCE::Util::get_ncpu(),
chunk_size => 40,
init_relay => '',
gather => sub {
if (@_ == 1) {
print "\r", $count++;
} else {
push @data, @{ $_[1] };
}
},
user_begin => sub {
$bkg = Imager->new(xsize=>800, ysize=>600);
$bkg->filter(type=>"gradgen",
xo=>[ 100, 300, 600 ],
yo=>[ 100, 300, 100 ],
colors=>[ qw(red blue green) ]);
$bkg->filter(type=>"noise", amount=>12, subtype=>0)
},
);
mce_loop {
my ($mce, $chunk_ref, $chunk_id) = @_;
my @i_data;
for my $x (@{ $chunk_ref }) {
my $i = $bkg-> copy;
$i->string(
text => $x,
color => Imager::Color->new('ffffff'),
font => Imager::Font->new(
# file => '/usr/share/fonts/truetype/msttcorefonts/cour.ttf',
# file => '/System/Library/Fonts/Courier.dfont',
face => 'Courier New', # mswin
size => 420,
aa => 1),
x => 25,
y => 500,
);
$i->write(data => \my $data, type => 'gif');
push @i_data, $data;
MCE->gather($x);
}
MCE::relay { MCE->gather($chunk_id, \@i_data) };
} [ 0 .. 319 ];
MCE::Loop->finish;
print " frame GIF done!\n";
printf "compute time: %0.3fs\n", time - $start;
if ( $TEST_GD ) {
my $image = GD::Image-> newFromGifData( $data[ 0 ]);
my $gifdata = $image-> gifanimbegin(0,0);
$gifdata .= $image-> gifanimadd( 1,0,0,1,1 );
for (1..$#data) {
my $frame = GD::Image-> newFromGifData( $data[ $_ ]);
$gifdata .= $frame-> gifanimadd( 1,0,0,1,1 );
}
$gifdata .= $image-> gifanimend;
open my $fh, '>', 'gd.gif';
binmode $fh;
print $fh $gifdata;
close $fh;
}
else {
Imager->write_multi({
file => 'im.gif', type => 'gif', gif_loop => 0, gif_delay => 1,
}, map { Imager->new(data => \$_) } @data) or die Imager->errstr;
}
printf "Total: %0.3fs\n", time - $start;
__END__
319 frame GIF done!
compute time: 10.932s
Total: 45.646s
319 frame GIF done!
compute time: 10.738s
Total: 17.107s
####
if ( $TEST_GD ) {
my $gd = GD::Image-> newFromGifData( $data );
push @i_data, !$x
? $gd-> gifanimbegin .
$gd-> gifanimadd( 1,0,0,1,1 )
: $gd-> gifanimadd( 1,0,0,1,1 )
}
else {
push @i_data, $data
}
##
##
if ( $TEST_GD ) {
open my $fh, '>', 'gd.gif';
binmode $fh;
print $fh join '', @data;
close $fh;
}
else {
Imager->write_multi({
file => 'im.gif', type => 'gif', gif_loop => 0, gif_delay => 1,
}, map { Imager->new(data => \$_) } @data) or die Imager->errstr;
}
__END__
319 frame GIF done!
compute time: 11.765s
Total: 12.015s