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