6 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR $fontstate %OPCODES $I2P $FORMATGUESS);
87 i_writetiff_wiol_faxable
158 $VERSION = '0.38pre9';
159 @ISA = qw(Exporter DynaLoader);
160 bootstrap Imager $VERSION;
164 i_init_fonts(); # Initialize font engines
165 for(i_list_formats()) { $formats{$_}++; }
167 if ($formats{'t1'}) {
171 if (!$formats{'t1'} and !$formats{'tt'}) {
172 $fontstate='no font support';
175 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
180 callseq => ['image','intensity'],
181 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
185 callseq => ['image', 'amount', 'subtype'],
186 defaults => { amount=>3,subtype=>0 },
187 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
190 $filters{hardinvert} ={
191 callseq => ['image'],
193 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
196 $filters{autolevels} ={
197 callseq => ['image','lsat','usat','skew'],
198 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
199 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
202 $filters{turbnoise} ={
203 callseq => ['image'],
204 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
205 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
208 $filters{radnoise} ={
209 callseq => ['image'],
210 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
211 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
215 callseq => ['image', 'coef'],
217 callsub => sub { my %hsh=@_; i_conv($hsh{image},$hsh{coef}); }
221 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
223 callsub => sub { my %hsh=@_; i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
226 $filters{nearest_color} ={
227 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
229 callsub => sub { my %hsh=@_; i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
232 $FORMATGUESS=\&def_guess_type;
240 # NOTE: this might be moved to an import override later on
244 # (look through @_ for special tags, process, and remove them);
246 # print Dumper($pack);
251 my %parms=(loglevel=>1,@_);
253 init_log($parms{'log'},$parms{'loglevel'});
256 # if ($parms{T1LIB_CONFIG}) { $ENV{T1LIB_CONFIG}=$parms{T1LIB_CONFIG}; }
257 # if ( $ENV{T1LIB_CONFIG} and ( $fontstate eq 'missing conf' )) {
265 print "shutdown code\n";
266 # for(keys %instances) { $instances{$_}->DESTROY(); }
267 malloc_state(); # how do decide if this should be used? -- store something from the import
268 print "Imager exiting\n";
272 # Load a filter plugin
277 my ($DSO_handle,$str)=DSO_open($filename);
278 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
279 my %funcs=DSO_funclist($DSO_handle);
280 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
282 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
284 $DSOs{$filename}=[$DSO_handle,\%funcs];
287 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
288 $DEBUG && print "eval string:\n",$evstr,"\n";
300 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
301 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
302 for(keys %{$funcref}) {
304 $DEBUG && print "unloading: $_\n";
306 my $rc=DSO_close($DSO_handle);
307 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
311 # take the results of i_error() and make a message out of it
313 return join(": ", map $_->[0], i_errors());
318 # Methods to be called on objects.
321 # Create a new Imager object takes very few parameters.
322 # usually you call this method and then call open from
323 # the resulting object
330 $self->{IMG}=undef; # Just to indicate what exists
331 $self->{ERRSTR}=undef; #
332 $self->{DEBUG}=$DEBUG;
333 $self->{DEBUG} && print "Initialized Imager\n";
334 if ($hsh{xsize} && $hsh{ysize}) { $self->img_set(%hsh); }
339 # Copy an entire image with no changes
340 # - if an image has magic the copy of it will not be magical
344 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
346 my $newcopy=Imager->new();
347 $newcopy->{IMG}=i_img_new();
348 i_copy($newcopy->{IMG},$self->{IMG});
356 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
357 my %input=(left=>0, top=>0, @_);
358 unless($input{img}) {
359 $self->{ERRSTR}="no source image";
362 $input{left}=0 if $input{left} <= 0;
363 $input{top}=0 if $input{top} <= 0;
365 my($r,$b)=i_img_info($src->{IMG});
367 i_copyto($self->{IMG}, $src->{IMG},
368 0,0, $r, $b, $input{left}, $input{top});
369 return $self; # What should go here??
372 # Crop an image - i.e. return a new image that is smaller
376 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
377 my %hsh=(left=>0,right=>0,top=>0,bottom=>0,@_);
379 my ($w,$h,$l,$r,$b,$t)=($self->getwidth(),$self->getheight(),
380 @hsh{qw(left right bottom top)});
381 $l=0 if not defined $l;
382 $t=0 if not defined $t;
384 $r||=$l+delete $hsh{'width'} if defined $l and exists $hsh{'width'};
385 $b||=$t+delete $hsh{'height'} if defined $t and exists $hsh{'height'};
386 $l||=$r-delete $hsh{'width'} if defined $r and exists $hsh{'width'};
387 $t||=$b-delete $hsh{'height'} if defined $b and exists $hsh{'height'};
389 $r=$self->getwidth if not defined $r;
390 $b=$self->getheight if not defined $b;
392 ($l,$r)=($r,$l) if $l>$r;
393 ($t,$b)=($b,$t) if $t>$b;
396 $l=int(0.5+($w-$hsh{'width'})/2);
401 if ($hsh{'height'}) {
402 $b=int(0.5+($h-$hsh{'height'})/2);
403 $t=$h+$hsh{'height'};
405 $hsh{'height'}=$b-$t;
408 # print "l=$l, r=$r, h=$hsh{'width'}\n";
409 # print "t=$t, b=$b, w=$hsh{'height'}\n";
411 my $dst=Imager->new(xsize=>$hsh{'width'}, ysize=>$hsh{'height'}, channels=>$self->getchannels());
413 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
417 # Sets an image to a certain size and channel number
418 # if there was previously data in the image it is discarded
423 my %hsh=(xsize=>100,ysize=>100,channels=>3,@_);
425 if (defined($self->{IMG})) {
426 i_img_destroy($self->{IMG});
430 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'},$hsh{'ysize'},$hsh{'channels'});
433 # Read an image from file
440 if (defined($self->{IMG})) {
441 i_img_destroy($self->{IMG});
445 if (!$input{fd} and !$input{file} and !$input{data}) { $self->{ERRSTR}='no file, fd or data parameter'; return undef; }
447 $fh = new IO::File($input{file},"r");
448 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
452 if ($input{fd}) { $fd=$input{fd} };
454 # FIXME: Find the format here if not specified
455 # yes the code isn't here yet - next week maybe?
457 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
458 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
460 my %iolready=(jpeg=>1, tiff=>1, pnm=>1);
462 if ($iolready{$input{type}}) {
464 $IO = io_new_fd($fd); # sort of simple for now eh?
466 if ( $input{type} eq 'jpeg' ) {
467 ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_wiol( $IO );
468 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read jpeg image'; return undef; }
469 $self->{DEBUG} && print "loading a jpeg file\n";
473 if ( $input{type} eq 'tiff' ) {
474 $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
475 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read tiff image'; return undef; }
476 $self->{DEBUG} && print "loading a tiff file\n";
480 if ( $input{type} eq 'pnm' ) {
481 $self->{IMG}=i_readpnm_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
482 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read pnm image: '._error_as_msg(); return undef; }
483 $self->{DEBUG} && print "loading a pnm file\n";
489 # Old code for reference while changing the new stuff
492 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
493 if (!$input{type}) { $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef; }
495 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
498 $fh = new IO::File($input{file},"r");
499 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
503 if ($input{fd}) { $fd=$input{fd} };
505 if ( $input{type} eq 'gif' ) {
507 if ($input{colors} && !ref($input{colors})) {
508 # must be a reference to a scalar that accepts the colour map
509 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
512 if (exists $input{data}) {
513 if ($input{colors}) {
514 ($self->{IMG}, $colors) = i_readgif_scalar($input{data});
517 $self->{IMG}=i_readgif_scalar($input{data});
521 if ($input{colors}) {
522 ($self->{IMG}, $colors) = i_readgif( $fd );
525 $self->{IMG} = i_readgif( $fd )
529 # we may or may not change i_readgif to return blessed objects...
530 ${$input{colors}} = [ map { NC(@$_) } @$colors ];
532 if ( !defined($self->{IMG}) ) {
533 $self->{ERRSTR}= 'reading GIF:'._error_as_msg(); return undef;
535 $self->{DEBUG} && print "loading a gif file\n";
536 } elsif ( $input{type} eq 'jpeg' ) {
537 if (exists $input{data}) { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_scalar($input{data}); }
538 else { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg( $fd ); }
539 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read jpeg image'; return undef; }
540 $self->{DEBUG} && print "loading a jpeg file\n";
541 } elsif ( $input{type} eq 'png' ) {
542 if (exists $input{data}) { $self->{IMG}=i_readpng_scalar($input{data}); }
543 else { $self->{IMG}=i_readpng( $fd ); }
544 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read png image'; return undef; }
545 $self->{DEBUG} && print "loading a png file\n";
546 } elsif ( $input{type} eq 'raw' ) {
547 my %params=(datachannels=>3,storechannels=>3,interleave=>1);
548 for(keys(%input)) { $params{$_}=$input{$_}; }
550 if ( !($params{xsize} && $params{ysize}) ) { $self->{ERRSTR}='missing xsize or ysize parameter for raw'; return undef; }
551 $self->{IMG}=i_readraw( $fd, $params{xsize}, $params{ysize},
552 $params{datachannels}, $params{storechannels}, $params{interleave});
553 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read raw image'; return undef; }
554 $self->{DEBUG} && print "loading a raw file\n";
561 # Write an image to file
565 my %input=(jpegquality=>75, gifquant=>'mc', lmdither=>6.0, lmfixed=>[],
567 my ($fh, $rc, $fd, $IO);
569 my %iolready=( tiff=>1 ); # this will be SO MUCH BETTER once they are all in there
571 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
573 if (!$input{file} and !$input{'fd'} and !$input{'data'}) { $self->{ERRSTR}='file/fd/data parameter missing'; return undef; }
574 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
575 if (!$input{type}) { $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef; }
577 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
579 if (exists $input{'fd'}) {
581 } elsif (exists $input{'data'}) {
582 $IO = Imager::io_new_bufchain();
584 $fh = new IO::File($input{file},"w+");
585 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
592 if ($iolready{$input{type}}) {
594 $IO = io_new_fd($fd);
597 if ($input{type} eq 'tiff') {
598 if (defined $input{class} && $input{class} eq 'fax') {
599 if (!i_writetiff_wiol_faxable($self->{IMG}, $IO, $input{fax_fine})) {
600 $self->{ERRSTR}='Could not write to buffer';
605 if (!i_writetiff_wiol($self->{IMG}, $IO)) {
606 $self->{ERRSTR}='Could not write to buffer';
612 if (exists $input{'data'}) {
613 my $data = io_slurp($IO);
615 $self->{ERRSTR}='Could not slurp from buffer';
618 ${$input{data}} = $data;
623 if ( $input{type} eq 'gif' ) {
624 if (not $input{gifplanes}) {
626 my $count=i_count_colors($self->{IMG}, 256);
627 $gp=8 if $count == -1;
628 $gp=1 if not $gp and $count <= 2;
629 $gp=2 if not $gp and $count <= 4;
630 $gp=3 if not $gp and $count <= 8;
631 $gp=4 if not $gp and $count <= 16;
632 $gp=5 if not $gp and $count <= 32;
633 $gp=6 if not $gp and $count <= 64;
634 $gp=7 if not $gp and $count <= 128;
635 $input{gifplanes} = $gp || 8;
638 if ($input{gifplanes}>8) {
641 if ($input{gifquant} eq 'gen' || $input{callback}) {
644 if ($input{gifquant} eq 'lm') {
646 $input{make_colors} = 'addi';
647 $input{translate} = 'perturb';
648 $input{perturb} = $input{lmdither};
649 } elsif ($input{gifquant} eq 'gen') {
650 # just pass options through
652 $input{make_colors} = 'webmap'; # ignored
653 $input{translate} = 'giflib';
656 if ($input{callback}) {
657 defined $input{maxbuffer} or $input{maxbuffer} = -1;
658 $rc = i_writegif_callback($input{callback}, $input{maxbuffer},
659 \%input, $self->{IMG});
661 $rc = i_writegif_gen($fd, \%input, $self->{IMG});
666 } elsif ($input{gifquant} eq 'lm') {
667 $rc=i_writegif($self->{IMG},$fd,$input{gifplanes},$input{lmdither},$input{lmfixed});
669 $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes});
671 if ( !defined($rc) ) {
672 $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef;
674 $self->{DEBUG} && print "writing a gif file\n";
676 } elsif ( $input{type} eq 'jpeg' ) {
677 $rc=i_writejpeg($self->{IMG},$fd,$input{jpegquality});
678 if ( !defined($rc) ) {
679 $self->{ERRSTR}='unable to write jpeg image'; return undef;
681 $self->{DEBUG} && print "writing a jpeg file\n";
682 } elsif ( $input{type} eq 'png' ) {
683 $rc=i_writepng($self->{IMG},$fd);
684 if ( !defined($rc) ) {
685 $self->{ERRSTR}='unable to write png image'; return undef;
687 $self->{DEBUG} && print "writing a png file\n";
688 } elsif ( $input{type} eq 'pnm' ) {
689 $rc=i_writeppm($self->{IMG},$fd);
690 if ( !defined($rc) ) {
691 $self->{ERRSTR}='unable to write pnm image'; return undef;
693 $self->{DEBUG} && print "writing a pnm file\n";
694 } elsif ( $input{type} eq 'raw' ) {
695 $rc=i_writeraw($self->{IMG},$fd);
696 if ( !defined($rc) ) {
697 $self->{ERRSTR}='unable to write raw image'; return undef;
699 $self->{DEBUG} && print "writing a raw file\n";
707 my ($class, $opts, @images) = @_;
709 if ($opts->{type} eq 'gif') {
710 my $gif_delays = $opts->{gif_delays};
711 local $opts->{gif_delays} = $gif_delays;
712 unless (ref $opts->{gif_delays}) {
713 # assume the caller wants the same delay for each frame
714 $opts->{gif_delays} = [ ($gif_delays) x @images ];
716 # translate to ImgRaw
717 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
718 $ERRSTR = "Usage: Imager->write_multi({ options }, @images)";
721 my @work = map $_->{IMG}, @images;
722 if ($opts->{callback}) {
723 # Note: you may need to fix giflib for this one to work
724 my $maxbuffer = $opts->{maxbuffer};
725 defined $maxbuffer or $maxbuffer = -1; # max by default
726 return i_writegif_callback($opts->{callback}, $maxbuffer,
730 return i_writegif_gen($opts->{fd}, $opts, @work);
733 my $fh = IO::File->new($opts->{file}, "w+");
735 $ERRSTR = "Error creating $opts->{file}: $!";
739 return i_writegif_gen(fileno($fh), $opts, @work);
743 $ERRSTR = "Sorry, write_multi doesn't support $opts->{type} yet";
748 # Destroy an Imager object
752 # delete $instances{$self};
753 if (defined($self->{IMG})) {
754 i_img_destroy($self->{IMG});
757 # print "Destroy Called on an empty image!\n"; # why did I put this here??
761 # Perform an inplace filter of an image
762 # that is the image will be overwritten with the data
768 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
770 if (!$input{type}) { $self->{ERRSTR}='type parameter missing'; return undef; }
772 if ( (grep { $_ eq $input{type} } keys %filters) != 1) {
773 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
776 if (defined($filters{$input{type}}{defaults})) {
777 %hsh=('image',$self->{IMG},%{$filters{$input{type}}{defaults}},%input);
779 %hsh=('image',$self->{IMG},%input);
782 my @cs=@{$filters{$input{type}}{callseq}};
785 if (!defined($hsh{$_})) {
786 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{type}; return undef;
790 &{$filters{$input{type}}{callsub}}(%hsh);
794 $self->{DEBUG} && print "callseq is: @cs\n";
795 $self->{DEBUG} && print "matching callseq is: @b\n";
800 # Scale an image to requested size and return the scaled version
804 my %opts=(scalefactor=>0.5,type=>'max',qtype=>'normal',@_);
805 my $img = Imager->new();
806 my $tmp = Imager->new();
808 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
810 if ($opts{xpixels} and $opts{ypixels} and $opts{type}) {
811 my ($xpix,$ypix)=( $opts{xpixels}/$self->getwidth() , $opts{ypixels}/$self->getheight() );
812 if ($opts{type} eq 'min') { $opts{scalefactor}=min($xpix,$ypix); }
813 if ($opts{type} eq 'max') { $opts{scalefactor}=max($xpix,$ypix); }
814 } elsif ($opts{xpixels}) { $opts{scalefactor}=$opts{xpixels}/$self->getwidth(); }
815 elsif ($opts{ypixels}) { $opts{scalefactor}=$opts{ypixels}/$self->getheight(); }
817 if ($opts{qtype} eq 'normal') {
818 $tmp->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
819 if ( !defined($tmp->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
820 $img->{IMG}=i_scaleaxis($tmp->{IMG},$opts{scalefactor},1);
821 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
824 if ($opts{'qtype'} eq 'preview') {
825 $img->{IMG}=i_scale_nn($self->{IMG},$opts{'scalefactor'},$opts{'scalefactor'});
826 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
829 $self->{ERRSTR}='scale: invalid value for qtype'; return undef;
832 # Scales only along the X axis
836 my %opts=(scalefactor=>0.5,@_);
838 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
840 my $img = Imager->new();
842 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getwidth(); }
844 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
845 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
847 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
851 # Scales only along the Y axis
855 my %opts=(scalefactor=>0.5,@_);
857 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
859 my $img = Imager->new();
861 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getheight(); }
863 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
864 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},1);
866 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
871 # Transform returns a spatial transformation of the input image
872 # this moves pixels to a new location in the returned image.
873 # NOTE - should make a utility function to check transforms for
878 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
880 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
882 # print Dumper(\%opts);
885 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
887 eval ("use Affix::Infix2Postfix;");
890 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
893 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
894 {op=>'-',trans=>'Sub'},
895 {op=>'*',trans=>'Mult'},
896 {op=>'/',trans=>'Div'},
897 {op=>'-',type=>'unary',trans=>'u-'},
899 {op=>'func',type=>'unary'}],
900 'grouping'=>[qw( \( \) )],
901 'func'=>[qw( sin cos )],
906 @xt=$I2P->translate($opts{'xexpr'});
907 @yt=$I2P->translate($opts{'yexpr'});
909 $numre=$I2P->{'numre'};
912 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
913 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
914 @{$opts{'parm'}}=@pt;
917 # print Dumper(\%opts);
919 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
920 $self->{ERRSTR}='transform: no xopcodes given.';
924 @op=@{$opts{'xopcodes'}};
926 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
927 $self->{ERRSTR}="transform: illegal opcode '$_'.";
930 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
936 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
937 $self->{ERRSTR}='transform: no yopcodes given.';
941 @op=@{$opts{'yopcodes'}};
943 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
944 $self->{ERRSTR}="transform: illegal opcode '$_'.";
947 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
952 if ( !exists $opts{'parm'}) {
953 $self->{ERRSTR}='transform: no parameter arg given.';
957 # print Dumper(\@ropx);
958 # print Dumper(\@ropy);
959 # print Dumper(\@ropy);
961 my $img = Imager->new();
962 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
963 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
971 my ($opts, @imgs) = @_;
974 # this is fairly big, delay loading it
975 eval "use Imager::Expr";
980 $opts->{variables} = [ qw(x y) ];
981 my ($width, $height) = @{$opts}{qw(width height)};
983 $width ||= $imgs[0]->getwidth();
984 $height ||= $imgs[0]->getheight();
986 for my $img (@imgs) {
987 $opts->{constants}{"w$img_num"} = $img->getwidth();
988 $opts->{constants}{"h$img_num"} = $img->getheight();
989 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
990 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
995 $opts->{constants}{w} = $width;
996 $opts->{constants}{cx} = $width/2;
999 $Imager::ERRSTR = "No width supplied";
1003 $opts->{constants}{h} = $height;
1004 $opts->{constants}{cy} = $height/2;
1007 $Imager::ERRSTR = "No height supplied";
1010 my $code = Imager::Expr->new($opts);
1012 $Imager::ERRSTR = Imager::Expr::error();
1016 my $img = Imager->new();
1017 $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
1018 $code->nregs(), $code->cregs(),
1019 [ map { $_->{IMG} } @imgs ]);
1020 if (!defined $img->{IMG}) {
1021 $Imager::ERRSTR = "transform2 failed";
1038 my %opts=(tx=>0,ty=>0,@_);
1040 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1041 unless ($opts{src} && $opts{src}->{IMG}) { $self->{ERRSTR}='empty input image for source'; return undef; }
1043 i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx},$opts{ty});
1051 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
1053 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
1054 $dir = $xlate{$opts{'dir'}};
1055 return $self if i_flipxy($self->{IMG}, $dir);
1061 # These two are supported for legacy code only
1064 return Imager::Color->new($_[0], $_[1], $_[2], $_[3]);
1068 return Imager::Color::set($_[0], $_[1], $_[2], $_[3], $_[4]);
1073 # Draws a box between the specified corner points.
1077 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1078 my $dflcl=i_color_new(255,255,255,255);
1079 my %opts=(color=>$dflcl,xmin=>0,ymin=>0,xmax=>$self->getwidth()-1,ymax=>$self->getheight()-1,@_);
1081 if (exists $opts{'box'}) {
1082 $opts{'xmin'} = min($opts{'box'}->[0],$opts{'box'}->[2]);
1083 $opts{'xmax'} = max($opts{'box'}->[0],$opts{'box'}->[2]);
1084 $opts{'ymin'} = min($opts{'box'}->[1],$opts{'box'}->[3]);
1085 $opts{'ymax'} = max($opts{'box'}->[1],$opts{'box'}->[3]);
1088 if ($opts{filled}) { i_box_filled($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1089 else { i_box($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1093 # Draws an arc - this routine SUCKS and is buggy - it sometimes doesn't work when the arc is a convex polygon
1097 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1098 my $dflcl=i_color_new(255,255,255,255);
1099 my %opts=(color=>$dflcl,
1100 'r'=>min($self->getwidth(),$self->getheight())/3,
1101 'x'=>$self->getwidth()/2,
1102 'y'=>$self->getheight()/2,
1103 'd1'=>0, 'd2'=>361, @_);
1104 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},$opts{'d2'},$opts{'color'});
1108 # Draws a line from one point to (but not including) the destination point
1112 my $dflcl=i_color_new(0,0,0,0);
1113 my %opts=(color=>$dflcl,@_);
1114 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1116 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
1117 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
1119 if ($opts{antialias}) {
1120 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1122 i_draw($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1127 # Draws a line between an ordered set of points - It more or less just transforms this
1128 # into a list of lines.
1132 my ($pt,$ls,@points);
1133 my $dflcl=i_color_new(0,0,0,0);
1134 my %opts=(color=>$dflcl,@_);
1136 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1138 if (exists($opts{points})) { @points=@{$opts{points}}; }
1139 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
1140 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
1143 # print Dumper(\@points);
1145 if ($opts{antialias}) {
1147 if (defined($ls)) { i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1152 if (defined($ls)) { i_draw($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1159 # this the multipoint bezier curve
1160 # this is here more for testing that actual usage since
1161 # this is not a good algorithm. Usually the curve would be
1162 # broken into smaller segments and each done individually.
1166 my ($pt,$ls,@points);
1167 my $dflcl=i_color_new(0,0,0,0);
1168 my %opts=(color=>$dflcl,@_);
1170 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1172 if (exists $opts{points}) {
1173 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
1174 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
1177 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
1178 $self->{ERRSTR}='Missing or invalid points.';
1182 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$opts{'color'});
1186 # make an identity matrix of the given size
1190 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
1191 for my $c (0 .. ($size-1)) {
1192 $matrix->[$c][$c] = 1;
1197 # general function to convert an image
1199 my ($self, %opts) = @_;
1202 # the user can either specify a matrix or preset
1203 # the matrix overrides the preset
1204 if (!exists($opts{matrix})) {
1205 unless (exists($opts{preset})) {
1206 $self->{ERRSTR} = "convert() needs a matrix or preset";
1210 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
1211 # convert to greyscale, keeping the alpha channel if any
1212 if ($self->getchannels == 3) {
1213 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
1215 elsif ($self->getchannels == 4) {
1216 # preserve the alpha channel
1217 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
1222 $matrix = _identity($self->getchannels);
1225 elsif ($opts{preset} eq 'noalpha') {
1226 # strip the alpha channel
1227 if ($self->getchannels == 2 or $self->getchannels == 4) {
1228 $matrix = _identity($self->getchannels);
1229 pop(@$matrix); # lose the alpha entry
1232 $matrix = _identity($self->getchannels);
1235 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
1237 $matrix = [ [ 1 ] ];
1239 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
1240 $matrix = [ [ 0, 1 ] ];
1242 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
1243 $matrix = [ [ 0, 0, 1 ] ];
1245 elsif ($opts{preset} eq 'alpha') {
1246 if ($self->getchannels == 2 or $self->getchannels == 4) {
1247 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
1250 # the alpha is just 1 <shrug>
1251 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
1254 elsif ($opts{preset} eq 'rgb') {
1255 if ($self->getchannels == 1) {
1256 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
1258 elsif ($self->getchannels == 2) {
1259 # preserve the alpha channel
1260 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
1263 $matrix = _identity($self->getchannels);
1266 elsif ($opts{preset} eq 'addalpha') {
1267 if ($self->getchannels == 1) {
1268 $matrix = _identity(2);
1270 elsif ($self->getchannels == 3) {
1271 $matrix = _identity(4);
1274 $matrix = _identity($self->getchannels);
1278 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
1284 $matrix = $opts{matrix};
1287 my $new = Imager->new();
1288 $new->{IMG} = i_img_new();
1289 unless (i_convert($new->{IMG}, $self->{IMG}, $matrix)) {
1290 # most likely a bad matrix
1291 $self->{ERRSTR} = _error_as_msg();
1298 # general function to map an image through lookup tables
1301 my ($self, %opts) = @_;
1302 my @chlist = qw( red green blue alpha );
1304 if (!exists($opts{'maps'})) {
1305 # make maps from channel maps
1307 for $chnum (0..$#chlist) {
1308 if (exists $opts{$chlist[$chnum]}) {
1309 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
1310 } elsif (exists $opts{'all'}) {
1311 $opts{'maps'}[$chnum] = $opts{'all'};
1315 if ($opts{'maps'} and $self->{IMG}) {
1316 i_map($self->{IMG}, $opts{'maps'} );
1332 # destructive border - image is shrunk by one pixel all around
1335 my ($self,%opts)=@_;
1336 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
1337 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
1341 # Get the width of an image
1345 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1346 return (i_img_info($self->{IMG}))[0];
1349 # Get the height of an image
1353 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1354 return (i_img_info($self->{IMG}))[1];
1357 # Get number of channels in an image
1361 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1362 return i_img_getchannels($self->{IMG});
1369 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1370 return i_img_getmask($self->{IMG});
1378 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1379 i_img_setmask( $self->{IMG} , $opts{mask} );
1382 # Get number of colors in an image
1386 my %opts=(maxcolors=>2**30,@_);
1387 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
1388 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
1389 return ($rc==-1? undef : $rc);
1392 # draw string to an image
1396 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1398 my %input=('x'=>0, 'y'=>0, @_);
1399 $input{string}||=$input{text};
1401 unless(exists $input{string}) {
1402 $self->{ERRSTR}="missing required parameter 'string'";
1406 unless($input{font}) {
1407 $self->{ERRSTR}="missing required parameter 'font'";
1412 my $font=$input{'font'};
1413 my $align=$font->{'align'} unless exists $input{'align'};
1414 my $color=$input{'color'} || $font->{'color'};
1415 my $size=$input{'size'} || $font->{'size'};
1417 if (!defined($size)) { $self->{ERRSTR}='No size parameter and no default in font'; return undef; }
1419 $aa=$font->{'aa'} if exists $font->{'aa'};
1420 $aa=$input{'aa'} if exists $input{'aa'};
1424 # unless($font->can('text')) {
1425 # $self->{ERRSTR}="font is unable to do what we need";
1430 # warn Dumper($font);
1432 # print "Channel=".$input{'channel'}."\n";
1434 if ( $font->{'type'} eq 't1' ) {
1435 if ( exists $input{'channel'} ) {
1436 Imager::Font::t1_set_aa_level($aa);
1437 i_t1_cp($self->{IMG},$input{'x'},$input{'y'},
1438 $input{'channel'},$font->{'id'},$size,
1439 $input{'string'},length($input{'string'}),1);
1441 Imager::Font::t1_set_aa_level($aa);
1442 i_t1_text($self->{IMG},$input{'x'},$input{'y'},
1443 $color,$font->{'id'},$size,
1444 $input{'string'},length($input{'string'}),1);
1448 if ( $font->{'type'} eq 'tt' ) {
1449 if ( exists $input{'channel'} ) {
1450 i_tt_cp($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$input{'channel'},
1451 $size,$input{'string'},length($input{'string'}),$aa);
1453 i_tt_text($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$color,$size,
1454 $input{'string'},length($input{'string'}),$aa);
1465 # Shortcuts that can be exported
1467 sub newcolor { Imager::Color->new(@_); }
1468 sub newfont { Imager::Font->new(@_); }
1470 *NC=*newcolour=*newcolor;
1477 #### Utility routines
1479 sub errstr { $_[0]->{ERRSTR} }
1486 # Default guess for the type of an image from extension
1488 sub def_guess_type {
1491 $ext=($name =~ m/\.([^\.]+)$/)[0];
1492 return 'tiff' if ($ext =~ m/^tiff?$/);
1493 return 'jpeg' if ($ext =~ m/^jpe?g$/);
1494 return 'pnm' if ($ext =~ m/^p[pgb]m$/);
1495 return 'png' if ($ext eq "png");
1496 return 'gif' if ($ext eq "gif");
1500 # get the minimum of a list
1504 for(@_) { if ($_<$mx) { $mx=$_; }}
1508 # get the maximum of a list
1512 for(@_) { if ($_>$mx) { $mx=$_; }}
1516 # string stuff for iptc headers
1520 $str = substr($str,3);
1521 $str =~ s/[\n\r]//g;
1528 # A little hack to parse iptc headers.
1533 my($caption,$photogr,$headln,$credit);
1535 my $str=$self->{IPTCRAW};
1539 @ar=split(/8BIM/,$str);
1544 @sar=split(/\034\002/);
1545 foreach $item (@sar) {
1546 if ($item =~ m/^x/) {
1547 $caption=&clean($item);
1550 if ($item =~ m/^P/) {
1551 $photogr=&clean($item);
1554 if ($item =~ m/^i/) {
1555 $headln=&clean($item);
1558 if ($item =~ m/^n/) {
1559 $credit=&clean($item);
1565 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
1573 # Autoload methods go after =cut, and are processed by the autosplit program.
1577 # Below is the stub of documentation for your module. You better edit it!
1581 Imager - Perl extension for Generating 24 bit Images
1585 use Imager qw(init);
1588 $img = Imager->new();
1589 $img->open(file=>'image.ppm',type=>'pnm')
1590 || print "failed: ",$img->{ERRSTR},"\n";
1591 $scaled=$img->scale(xpixels=>400,ypixels=>400);
1592 $scaled->write(file=>'sc_image.ppm',type=>'pnm')
1593 || print "failed: ",$scaled->{ERRSTR},"\n";
1597 Imager is a module for creating and altering images - It is not meant
1598 as a replacement or a competitor to ImageMagick or GD. Both are
1599 excellent packages and well supported.
1603 Almost all functions take the parameters in the hash fashion.
1606 $img->open(file=>'lena.png',type=>'png');
1610 $img->open(file=>'lena.png');
1612 =head2 Basic concept
1614 An Image object is created with C<$img = Imager-E<gt>new()> Should
1615 this fail for some reason an explanation can be found in
1616 C<$Imager::ERRSTR> usually error messages are stored in
1617 C<$img-E<gt>{ERRSTR}>, but since no object is created this is the only
1618 way to give back errors. C<$Imager::ERRSTR> is also used to report
1619 all errors not directly associated with an image object. Examples:
1621 $img=Imager->new(); # This is an empty image (size is 0 by 0)
1622 $img->open(file=>'lena.png',type=>'png'); # initializes from file
1624 or if you want to create an empty image:
1626 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
1628 This example creates a completely black image of width 400 and
1629 height 300 and 4 channels.
1631 If you have an existing image, use img_set() to change it's dimensions
1632 - this will destroy any existing image data:
1634 $img->img_set(xsize=>500, ysize=>500, channels=>4);
1636 Color objects are created by calling the Imager::Color->new()
1639 $color = Imager::Color->new($red, $green, $blue);
1640 $color = Imager::Color->new($red, $green, $blue, $alpha);
1641 $color = Imager::Color->new("#C0C0FF"); # html color specification
1643 This object can then be passed to functions that require a color parameter.
1645 Coordinates in Imager have the origin in the upper left corner. The
1646 horizontal coordinate increases to the right and the vertical
1649 =head2 Reading and writing images
1651 C<$img-E<gt>read()> generally takes two parameters, 'file' and 'type'.
1652 If the type of the file can be determined from the suffix of the file
1653 it can be omitted. Format dependant parameters are: For images of
1654 type 'raw' two extra parameters are needed 'xsize' and 'ysize', if the
1655 'channel' parameter is omitted for type 'raw' it is assumed to be 3.
1656 gif and png images might have a palette are converted to truecolor bit
1657 when read. Alpha channel is preserved for png images irregardless of
1658 them being in RGB or gray colorspace. Similarly grayscale jpegs are
1659 one channel images after reading them. For jpeg images the iptc
1660 header information (stored in the APP13 header) is avaliable to some
1661 degree. You can get the raw header with C<$img-E<gt>{IPTCRAW}>, but
1662 you can also retrieve the most basic information with
1663 C<%hsh=$img-E<gt>parseiptc()> as always patches are welcome. pnm has no
1664 extra options. Examples:
1666 $img = Imager->new();
1667 $img->read(file=>"cover.jpg") or die $img->errstr; # gets type from name
1669 $img = Imager->new();
1670 { local(*FH,$/); open(FH,"file.gif") or die $!; $a=<FH>; }
1671 $img->read(data=>$a,type=>'gif') or die $img->errstr;
1673 The second example shows how to read an image from a scalar, this is
1674 usefull if your data originates from somewhere else than a filesystem
1675 such as a database over a DBI connection.
1677 When writing to a tiff image file you can also specify the 'class'
1678 parameter, which can currently take a single value, "fax". If class
1679 is set to fax then a tiff image which should be suitable for faxing
1680 will be written. For the best results start with a grayscale image.
1681 By default the image is written at fine resolution you can override
1682 this by setting the "fax_fine" parameter to 0.
1684 If you are reading from a gif image file, you can supply a 'colors'
1685 parameter which must be a reference to a scalar. The referenced
1686 scalar will receive an array reference which contains the colors, each
1687 represented as an Imager::Color object.
1689 If you already have an open file handle, for example a socket or a
1690 pipe, you can specify the 'fd' parameter instead of supplying a
1691 filename. Please be aware that you need to use fileno() to retrieve
1692 the file descriptor for the file:
1694 $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr;
1696 For writing using the 'fd' option you will probably want to set $| for
1697 that descriptor, since the writes to the file descriptor bypass Perl's
1698 (or the C libraries) buffering. Setting $| should avoid out of order
1701 *Note that load() is now an alias for read but will be removed later*
1703 C<$img-E<gt>write> has the same interface as C<read()>. The earlier
1704 comments on C<read()> for autodetecting filetypes apply. For jpegs
1705 quality can be adjusted via the 'jpegquality' parameter (0-100). The
1706 number of colorplanes in gifs are set with 'gifplanes' and should be
1707 between 1 (2 color) and 8 (256 colors). It is also possible to choose
1708 between two quantizing methods with the parameter 'gifquant'. If set
1709 to mc it uses the mediancut algorithm from either giflibrary. If set
1710 to lm it uses a local means algorithm. It is then possible to give
1711 some extra settings. lmdither is the dither deviation amount in pixels
1712 (manhattan distance). lmfixed can be an array ref who holds an array
1713 of Imager::Color objects. Note that the local means algorithm needs
1714 much more cpu time but also gives considerable better results than the
1715 median cut algorithm.
1717 Currently just for gif files, you can specify various options for the
1718 conversion from Imager's internal RGB format to the target's indexed
1719 file format. If you set the gifquant option to 'gen', you can use the
1720 options specified under L<Quantization options>.
1722 To see what Imager is compiled to support the following code snippet
1726 print "@{[keys %Imager::formats]}";
1728 When reading raw images you need to supply the width and height of the
1729 image in the xsize and ysize options:
1731 $img->read(file=>'foo.raw', xsize=>100, ysize=>100)
1732 or die "Cannot read raw image\n";
1734 If your input file has more channels than you want, or (as is common),
1735 junk in the fourth channel, you can use the datachannels and
1736 storechannels options to control the number of channels in your input
1737 file and the resulting channels in your image. For example, if your
1738 input image uses 32-bits per pixel with red, green, blue and junk
1739 values for each pixel you could do:
1741 $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4,
1743 or die "Cannot read raw image\n";
1745 Normally the raw image is expected to have the value for channel 1
1746 immediately following channel 0 and channel 2 immediately following
1747 channel 1 for each pixel. If your input image has all the channel 0
1748 values for the first line of the image, followed by all the channel 1
1749 values for the first line and so on, you can use the interleave option:
1751 $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1)
1752 or die "Cannot read raw image\n";
1754 =head2 Multi-image files
1756 Currently just for gif files, you can create files that contain more
1761 Imager->write_multi(\%opts, @images)
1763 Where %opts describes 4 possible types of outputs:
1769 This is C<gif> for gif animations.
1773 A code reference which is called with a single parameter, the data to
1774 be written. You can also specify $opts{maxbuffer} which is the
1775 maximum amount of data buffered. Note that there can be larger writes
1776 than this if the file library writes larger blocks. A smaller value
1777 maybe useful for writing to a socket for incremental display.
1781 The file descriptor to save the images to.
1785 The name of the file to write to.
1787 %opts may also include the keys from L<Gif options> and L<Quantization
1792 You must also specify the file format using the 'type' option.
1794 The current aim is to support other multiple image formats in the
1795 future, such as TIFF, and to support reading multiple images from a
1801 # ... code to put images in @images
1802 Imager->write_multi({type=>'gif',
1804 gif_delays=>[ (10) x @images ] },
1810 These options can be specified when calling write_multi() for gif
1811 files, when writing a single image with the gifquant option set to
1812 'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
1814 Note that some viewers will ignore some of these options
1815 (gif_user_input in particular).
1819 =item gif_each_palette
1821 Each image in the gif file has it's own palette if this is non-zero.
1822 All but the first image has a local colour table (the first uses the
1823 global colour table.
1827 The images are written interlaced if this is non-zero.
1831 A reference to an array containing the delays between images, in 1/100
1834 If you want the same delay for every frame you can simply set this to
1835 the delay in 1/100 seconds.
1837 =item gif_user_input
1839 A reference to an array contains user input flags. If the given flag
1840 is non-zero the image viewer should wait for input before displaying
1845 A reference to an array of image disposal methods. These define what
1846 should be done to the image before displaying the next one. These are
1847 integers, where 0 means unspecified, 1 means the image should be left
1848 in place, 2 means restore to background colour and 3 means restore to
1851 =item gif_tran_color
1853 A reference to an Imager::Color object, which is the colour to use for
1854 the palette entry used to represent transparency in the palette. You
1855 need to set the transp option (see L<Quantization options>) for this
1860 A reference to an array of references to arrays which represent screen
1861 positions for each image.
1863 =item gif_loop_count
1865 If this is non-zero the Netscape loop extension block is generated,
1866 which makes the animation of the images repeat.
1868 This is currently unimplemented due to some limitations in giflib.
1872 =head2 Quantization options
1874 These options can be specified when calling write_multi() for gif
1875 files, when writing a single image with the gifquant option set to
1876 'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
1882 A arrayref of colors that are fixed. Note that some color generators
1887 The type of transparency processing to perform for images with an
1888 alpha channel where the output format does not have a proper alpha
1889 channel (eg. gif). This can be any of:
1895 No transparency processing is done. (default)
1899 Pixels more transparent that tr_threshold are rendered as transparent.
1903 An error diffusion dither is done on the alpha channel. Note that
1904 this is independent of the translation performed on the colour
1905 channels, so some combinations may cause undesired artifacts.
1909 The ordered dither specified by tr_orddith is performed on the alpha
1914 This will only be used if the image has an alpha channel, and if there
1915 is space in the palette for a transparency colour.
1919 The highest alpha value at which a pixel will be made transparent when
1920 transp is 'threshold'. (0-255, default 127)
1924 The type of error diffusion to perform on the alpha channel when
1925 transp is 'errdiff'. This can be any defined error diffusion type
1926 except for custom (see errdiff below).
1930 The type of ordered dither to perform on the alpha channel when transp
1931 is 'ordered'. Possible values are:
1937 A semi-random map is used. The map is the same each time.
1949 horizontal line dither.
1953 vertical line dither.
1959 diagonal line dither
1965 diagonal line dither
1969 dot matrix dither (currently the default). This is probably the best
1970 for displays (like web pages).
1974 A custom dither matrix is used - see tr_map
1980 When tr_orddith is custom this defines an 8 x 8 matrix of integers
1981 representing the transparency threshold for pixels corresponding to
1982 each position. This should be a 64 element array where the first 8
1983 entries correspond to the first row of the matrix. Values should be
1988 Defines how the quantization engine will build the palette(s).
1989 Currently this is ignored if 'translate' is 'giflib', but that may
1990 change. Possible values are:
1996 Only colors supplied in 'colors' are used.
2000 The web color map is used (need url here.)
2004 The original code for generating the color map (Addi's code) is used.
2008 Other methods may be added in the future.
2012 A arrayref containing Imager::Color objects, which represents the
2013 starting set of colors to use in translating the images. webmap will
2014 ignore this. The final colors used are copied back into this array
2015 (which is expanded if necessary.)
2019 The maximum number of colors to use in the image.
2023 The method used to translate the RGB values in the source image into
2024 the colors selected by make_colors. Note that make_colors is ignored
2025 whene translate is 'giflib'.
2027 Possible values are:
2033 The giflib native quantization function is used.
2037 The closest color available is used.
2041 The pixel color is modified by perturb, and the closest color is chosen.
2045 An error diffusion dither is performed.
2049 It's possible other transate values will be added.
2053 The type of error diffusion dither to perform. These values (except
2054 for custom) can also be used in tr_errdif.
2060 Floyd-Steinberg dither
2064 Jarvis, Judice and Ninke dither
2072 Custom. If you use this you must also set errdiff_width,
2073 errdiff_height and errdiff_map.
2079 =item errdiff_height
2085 When translate is 'errdiff' and errdiff is 'custom' these define a
2086 custom error diffusion map. errdiff_width and errdiff_height define
2087 the size of the map in the arrayref in errdiff_map. errdiff_orig is
2088 an integer which indicates the current pixel position in the top row
2093 When translate is 'perturb' this is the magnitude of the random bias
2094 applied to each channel of the pixel before it is looked up in the
2099 =head2 Obtaining/setting attributes of images
2101 To get the size of an image in pixels the C<$img-E<gt>getwidth()> and
2102 C<$img-E<gt>getheight()> are used.
2104 To get the number of channels in
2105 an image C<$img-E<gt>getchannels()> is used. $img-E<gt>getmask() and
2106 $img-E<gt>setmask() are used to get/set the channel mask of the image.
2108 $mask=$img->getmask();
2109 $img->setmask(mask=>1+2); # modify red and green only
2110 $img->setmask(mask=>8); # modify alpha only
2111 $img->setmask(mask=>$mask); # restore previous mask
2113 The mask of an image describes which channels are updated when some
2114 operation is performed on an image. Naturally it is not possible to
2115 apply masks to operations like scaling that alter the dimensions of
2118 It is possible to have Imager find the number of colors in an image
2119 by using C<$img-E<gt>getcolorcount()>. It requires memory proportionally
2120 to the number of colors in the image so it is possible to have it
2121 stop sooner if you only need to know if there are more than a certain number
2122 of colors in the image. If there are more colors than asked for
2123 the function return undef. Examples:
2125 if (!defined($img->getcolorcount(maxcolors=>512)) {
2126 print "Less than 512 colors in image\n";
2129 =head2 Drawing Methods
2131 IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS
2132 DOCUMENTATION OF THIS SECTION OUT OF SYNC
2134 It is possible to draw with graphics primitives onto images. Such
2135 primitives include boxes, arcs, circles and lines. A reference
2136 oriented list follows.
2139 $img->box(color=>$blue,xmin=>10,ymin=>30,xmax=>200,ymax=>300,filled=>1);
2141 The above example calls the C<box> method for the image and the box
2142 covers the pixels with in the rectangle specified. If C<filled> is
2143 ommited it is drawn as an outline. If any of the edges of the box are
2144 ommited it will snap to the outer edge of the image in that direction.
2145 Also if a color is omitted a color with (255,255,255,255) is used
2149 $img->arc(color=>$red, r=20, x=>200, y=>100, d1=>10, d2=>20 );
2151 This creates a filled red arc with a 'center' at (200, 100) and spans
2152 10 degrees and the slice has a radius of 20. SEE section on BUGS.
2155 $img->circle(color=>$green, r=50, x=>200, y=>100);
2157 This creates a green circle with its center at (200, 100) and has a
2161 $img->line(color=>$green, x1=10, x2=>100,
2162 y1=>20, y2=>50, antialias=>1 );
2164 That draws an antialiased line from (10,100) to (20,50).
2167 $img->polyline(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2]],color=>$red);
2168 $img->polyline(x=>[$x0,$x1,$x2], y=>[$y0,$y1,$y2], antialias=>1);
2170 Polyline is used to draw multilple lines between a series of points.
2171 The point set can either be specified as an arrayref to an array of
2172 array references (where each such array represents a point). The
2173 other way is to specify two array references.
2175 =head2 Text rendering
2177 Text rendering is described in the Imager::Font manpage.
2179 =head2 Image resizing
2181 To scale an image so porportions are maintained use the
2182 C<$img-E<gt>scale()> method. if you give either a xpixels or ypixels
2183 parameter they will determine the width or height respectively. If
2184 both are given the one resulting in a larger image is used. example:
2185 C<$img> is 700 pixels wide and 500 pixels tall.
2187 $img->scale(xpixels=>400); # 400x285
2188 $img->scale(ypixels=>400); # 560x400
2190 $img->scale(xpixels=>400,ypixels=>400); # 560x400
2191 $img->scale(xpixels=>400,ypixels=>400,type=>min); # 400x285
2193 $img->scale(scalefactor=>0.25); 175x125 $img->scale(); # 350x250
2195 if you want to create low quality previews of images you can pass
2196 C<qtype=E<gt>'preview'> to scale and it will use nearest neighbor
2197 sampling instead of filtering. It is much faster but also generates
2198 worse looking images - especially if the original has a lot of sharp
2199 variations and the scaled image is by more than 3-5 times smaller than
2202 If you need to scale images per axis it is best to do it simply by
2203 calling scaleX and scaleY. You can pass either 'scalefactor' or
2204 'pixels' to both functions.
2206 Another way to resize an image size is to crop it. The parameters
2207 to crop are the edges of the area that you want in the returned image.
2208 If a parameter is omited a default is used instead.
2210 $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100);
2211 $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
2212 $newimg = $img->crop(left=>50, right=>100); # top
2214 You can also specify width and height parameters which will produce a
2215 new image cropped from the center of the input image, with the given
2218 $newimg = $img->crop(width=>50, height=>50);
2220 The width and height parameters take precedence over the left/right
2221 and top/bottom parameters respectively.
2223 =head2 Copying images
2225 To create a copy of an image use the C<copy()> method. This is usefull
2226 if you want to keep an original after doing something that changes the image
2227 inplace like writing text.
2231 To copy an image to onto another image use the C<paste()> method.
2233 $dest->paste(left=>40,top=>20,img=>$logo);
2235 That copies the entire C<$logo> image onto the C<$dest> image so that the
2236 upper left corner of the C<$logo> image is at (40,20).
2239 =head2 Flipping images
2241 An inplace horizontal or vertical flip is possible by calling the
2242 C<flip()> method. If the original is to be preserved it's possible to
2243 make a copy first. The only parameter it takes is the C<dir>
2244 parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
2246 $img->flip(dir=>"h"); # horizontal flip
2247 $img->flip(dir=>"vh"); # vertical and horizontal flip
2248 $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
2250 =head2 Blending Images
2252 To put an image or a part of an image directly
2253 into another it is best to call the C<paste()> method on the image you
2256 $img->paste(img=>$srcimage,left=>30,top=>50);
2258 That will take paste C<$srcimage> into C<$img> with the upper
2259 left corner at (30,50). If no values are given for C<left>
2260 or C<top> they will default to 0.
2262 A more complicated way of blending images is where one image is
2263 put 'over' the other with a certain amount of opaqueness. The
2264 method that does this is rubthrough.
2266 $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
2268 That will take the image C<$srcimage> and overlay it with the
2269 upper left corner at (30,50). The C<$srcimage> must be a 4 channel
2270 image. The last channel is used as an alpha channel.
2275 A special image method is the filter method. An example is:
2277 $img->filter(type=>'autolevels');
2279 This will call the autolevels filter. Here is a list of the filters
2280 that are always avaliable in Imager. This list can be obtained by
2281 running the C<filterlist.perl> script that comes with the module
2286 autolevels lsat(0.1) usat(0.1) skew(0)
2288 noise amount(3) subtype(0)
2291 gradgen xo yo colors dist
2293 The default values are in parenthesis. All parameters must have some
2294 value but if a parameter has a default value it may be omitted when
2295 calling the filter function.
2297 FIXME: make a seperate pod for filters?
2299 =head2 Color transformations
2301 You can use the convert method to transform the color space of an
2302 image using a matrix. For ease of use some presets are provided.
2304 The convert method can be used to:
2310 convert an RGB or RGBA image to grayscale.
2314 convert a grayscale image to RGB.
2318 extract a single channel from an image.
2322 set a given channel to a particular value (or from another channel)
2326 The currently defined presets are:
2334 converts an RGBA image into a grayscale image with alpha channel, or
2335 an RGB image into a grayscale image without an alpha channel.
2337 This weights the RGB channels at 22.2%, 70.7% and 7.1% respectively.
2341 removes the alpha channel from a 2 or 4 channel image. An identity
2348 extracts the first channel of the image into a single channel image
2354 extracts the second channel of the image into a single channel image
2360 extracts the third channel of the image into a single channel image
2364 extracts the alpha channel of the image into a single channel image.
2366 If the image has 1 or 3 channels (assumed to be grayscale of RGB) then
2367 the resulting image will be all white.
2371 converts a grayscale image to RGB, preserving the alpha channel if any
2375 adds an alpha channel to a grayscale or RGB image. Preserves an
2376 existing alpha channel for a 2 or 4 channel image.
2380 For example, to convert an RGB image into a greyscale image:
2382 $new = $img->convert(preset=>'grey'); # or gray
2384 or to convert a grayscale image to an RGB image:
2386 $new = $img->convert(preset=>'rgb');
2388 The presets aren't necessary simple constants in the code, some are
2389 generated based on the number of channels in the input image.
2391 If you want to perform some other colour transformation, you can use
2392 the 'matrix' parameter.
2394 For each output pixel the following matrix multiplication is done:
2396 channel[0] [ [ $c00, $c01, ... ] inchannel[0]
2397 [ ... ] = ... x [ ... ]
2398 channel[n-1] [ $cn0, ..., $cnn ] ] inchannel[max]
2401 So if you want to swap the red and green channels on a 3 channel image:
2403 $new = $img->convert(matrix=>[ [ 0, 1, 0 ],
2407 or to convert a 3 channel image to greyscale using equal weightings:
2409 $new = $img->convert(matrix=>[ [ 0.333, 0.333, 0.334 ] ])
2411 =head2 Color Mappings
2413 You can use the map method to map the values of each channel of an
2414 image independently using a list of lookup tables. It's important to
2415 realize that the modification is made inplace. The function simply
2416 returns the input image again or undef on failure.
2418 Each channel is mapped independently through a lookup table with 256
2419 entries. The elements in the table should not be less than 0 and not
2420 greater than 255. If they are out of the 0..255 range they are
2421 clamped to the range. If a table does not contain 256 entries it is
2424 Single channels can mapped by specifying their name and the mapping
2425 table. The channel names are C<red>, C<green>, C<blue>, C<alpha>.
2427 @map = map { int( $_/2 } 0..255;
2428 $img->map( red=>\@map );
2430 It is also possible to specify a single map that is applied to all
2431 channels, alpha channel included. For example this applies a gamma
2432 correction with a gamma of 1.4 to the input image.
2435 @map = map { int( 0.5 + 255*($_/255)**$gamma ) } 0..255;
2436 $img->map(all=> \@map);
2438 The C<all> map is used as a default channel, if no other map is
2439 specified for a channel then the C<all> map is used instead. If we
2440 had not wanted to apply gamma to the alpha channel we would have used:
2442 $img->map(all=> \@map, alpha=>[]);
2444 Since C<[]> contains fewer than 256 element the gamma channel is
2447 It is also possible to simply specify an array of maps that are
2448 applied to the images in the rgba order. For example to apply
2449 maps to the C<red> and C<blue> channels one would use:
2451 $img->map(maps=>[\@redmap, [], \@bluemap]);
2455 =head2 Transformations
2457 Another special image method is transform. It can be used to generate
2458 warps and rotations and such features. It can be given the operations
2459 in postfix notation or the module Affix::Infix2Postfix can be used.
2460 Look in the test case t/t55trans.t for an example.
2462 transform() needs expressions (or opcodes) that determine the source
2463 pixel for each target pixel. Source expressions are infix expressions
2464 using any of the +, -, *, / or ** binary operators, the - unary
2465 operator, ( and ) for grouping and the sin() and cos() functions. The
2466 target pixel is input as the variables x and y.
2468 You specify the x and y expressions as xexpr and yexpr respectively.
2469 You can also specify opcodes directly, but that's magic deep enough
2470 that you can look at the source code.
2472 You can still use the transform() function, but the transform2()
2473 function is just as fast and is more likely to be enhanced and
2476 Later versions of Imager also support a transform2() class method
2477 which allows you perform a more general set of operations, rather than
2478 just specifying a spatial transformation as with the transform()
2479 method, you can also perform colour transformations, image synthesis
2480 and image combinations.
2482 transform2() takes an reference to an options hash, and a list of
2483 images to operate one (this list may be empty):
2488 my $img = Imager::transform2(\%opts, @imgs)
2489 or die "transform2 failed: $Imager::ERRSTR";
2491 The options hash may define a transformation function, and optionally:
2497 width - the width of the image in pixels. If this isn't supplied the
2498 width of the first input image is used. If there are no input images
2503 height - the height of the image in pixels. If this isn't supplied
2504 the height of the first input image is used. If there are no input
2505 images an error occurs.
2509 constants - a reference to hash of constants to define for the
2510 expression engine. Some extra constants are defined by Imager
2514 The tranformation function is specified using either the expr or
2515 rpnexpr member of the options.
2519 =item Infix expressions
2521 You can supply infix expressions to transform 2 with the expr keyword.
2523 $opts{expr} = 'return getp1(w-x, h-y)'
2525 The 'expression' supplied follows this general grammar:
2527 ( identifier '=' expr ';' )* 'return' expr
2529 This allows you to simplify your expressions using variables.
2531 A more complex example might be:
2533 $opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)'
2535 Currently to use infix expressions you must have the Parse::RecDescent
2536 module installed (available from CPAN). There is also what might be a
2537 significant delay the first time you run the infix expression parser
2538 due to the compilation of the expression grammar.
2540 =item Postfix expressions
2542 You can supply postfix or reverse-polish notation expressions to
2543 transform2() through the rpnexpr keyword.
2545 The parser for rpnexpr emulates a stack machine, so operators will
2546 expect to see their parameters on top of the stack. A stack machine
2547 isn't actually used during the image transformation itself.
2549 You can store the value at the top of the stack in a variable called
2550 foo using !foo and retrieve that value again using @foo. The !foo
2551 notation will pop the value from the stack.
2553 An example equivalent to the infix expression above:
2555 $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp'
2559 transform2() has a fairly rich range of operators.
2563 =item +, *, -, /, %, **
2565 multiplication, addition, subtraction, division, remainder and
2566 exponentiation. Multiplication, addition and subtraction can be used
2567 on colour values too - though you need to be careful - adding 2 white
2568 values together and multiplying by 0.5 will give you grey, not white.
2570 Division by zero (or a small number) just results in a large number.
2571 Modulo zero (or a small number) results in zero.
2573 =item sin(N), cos(N), atan2(y,x)
2575 Some basic trig functions. They work in radians, so you can't just
2578 =item distance(x1, y1, x2, y2)
2580 Find the distance between two points. This is handy (along with
2581 atan2()) for producing circular effects.
2585 Find the square root. I haven't had much use for this since adding
2586 the distance() function.
2590 Find the absolute value.
2592 =item getp1(x,y), getp2(x,y), getp3(x, y)
2594 Get the pixel at position (x,y) from the first, second or third image
2595 respectively. I may add a getpn() function at some point, but this
2596 prevents static checking of the instructions against the number of
2597 images actually passed in.
2599 =item value(c), hue(c), sat(c), hsv(h,s,v)
2601 Separates a colour value into it's value (brightness), hue (colour)
2602 and saturation elements. Use hsv() to put them back together (after
2603 suitable manipulation).
2605 =item red(c), green(c), blue(c), rgb(r,g,b)
2607 Separates a colour value into it's red, green and blue colours. Use
2608 rgb(r,g,b) to put it back together.
2612 Convert a value to an integer. Uses a C int cast, so it may break on
2615 =item if(cond,ntrue,nfalse), if(cond,ctrue,cfalse)
2617 A simple (and inefficient) if function.
2619 =item <=,<,==,>=,>,!=
2621 Relational operators (typically used with if()). Since we're working
2622 with floating point values the equalities are 'near equalities' - an
2623 epsilon value is used.
2625 =item &&, ||, not(n)
2627 Basic logical operators.
2635 =item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp'
2637 tiles a smaller version of the input image over itself where the
2638 colour has a saturation over 0.7.
2640 =item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd'
2642 tiles the input image over itself so that at the top of the image the
2643 full-size image is at full strength and at the bottom the tiling is
2646 =item rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp'
2648 replace pixels that are white or almost white with a palish blue
2650 =item rpnexpr=>'x 35 % 10 * y 45 % 8 * getp1 !pat x y getp1 !pix @pix sat 0.2 lt @pix value 0.9 gt and @pix @pat @pix value 2 / 0.5 + pmult ifp'
2652 Tiles the input image overitself where the image isn't white or almost
2655 =item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
2659 =item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
2661 A spiral built on top of a colour wheel.
2665 For details on expression parsing see L<Imager::Expr>. For details on
2666 the virtual machine used to transform the images, see
2667 L<Imager::regmach.pod>.
2671 It is possible to add filters to the module without recompiling the
2672 module itself. This is done by using DSOs (Dynamic shared object)
2673 avaliable on most systems. This way you can maintain our own filters
2674 and not have to get me to add it, or worse patch every new version of
2675 the Module. Modules can be loaded AND UNLOADED at runtime. This
2676 means that you can have a server/daemon thingy that can do something
2679 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2680 %hsh=(a=>35,b=>200,type=>lin_stretch);
2682 unload_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2683 $img->write(type=>'pnm',file=>'testout/t60.jpg')
2684 || die "error in write()\n";
2686 Someone decides that the filter is not working as it should -
2687 dyntest.c modified and recompiled.
2689 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2692 An example plugin comes with the module - Please send feedback to
2693 addi@umich.edu if you test this.
2695 Note: This seems to test ok on the following systems:
2696 Linux, Solaris, HPUX, OpenBSD, FreeBSD, TRU64/OSF1, AIX.
2697 If you test this on other systems please let me know.
2701 box, arc, circle do not support antialiasing yet. arc, is only filled
2702 as of yet. Some routines do not return $self where they should. This
2703 affects code like this, C<$img-E<gt>box()-E<gt>arc()> where an object
2706 When saving Gif images the program does NOT try to shave of extra
2707 colors if it is possible. If you specify 128 colors and there are
2708 only 2 colors used - it will have a 128 colortable anyway.
2712 Arnar M. Hrafnkelsson, addi@umich.edu, and recently lots of assistance
2713 from Tony Cook. See the README for a complete list.
2717 perl(1), Imager::Color(3), Imager::Font, Affix::Infix2Postfix(3),
2718 Parse::RecDescent(3) http://www.eecs.umich.edu/~addi/perl/Imager/