4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR %OPCODES $I2P $FORMATGUESS $warn_obsolete);
113 # registered file readers
116 # registered file writers
119 # modules we attempted to autoload
120 my %attempted_to_load;
122 # errors from loading files
123 my %file_load_errors;
125 # what happened when we tried to load
126 my %reader_load_errors;
127 my %writer_load_errors;
129 # library keys that are image file formats
130 my %file_formats = map { $_ => 1 } qw/tiff pnm gif png jpeg raw bmp tga/;
132 # image pixel combine types
134 qw/none normal multiply dissolve add subtract diff lighten darken
135 hue saturation value color/;
137 @combine_types{@combine_types} = 0 .. $#combine_types;
138 $combine_types{mult} = $combine_types{multiply};
139 $combine_types{'sub'} = $combine_types{subtract};
140 $combine_types{sat} = $combine_types{saturation};
142 # this will be used to store global defaults at some point
147 my $ex_version = eval $Exporter::VERSION;
148 if ($ex_version < 5.57) {
154 XSLoader::load(Imager => $VERSION);
158 push @ISA, 'DynaLoader';
159 bootstrap Imager $VERSION;
166 png => "Imager::File::PNG",
167 gif => "Imager::File::GIF",
168 tiff => "Imager::File::TIFF",
169 jpeg => "Imager::File::JPEG",
170 w32 => "Imager::Font::W32",
171 ft2 => "Imager::Font::FT2",
172 t1 => "Imager::Font::T1",
175 tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
178 for(i_list_formats()) { $formats_low{$_}++; }
180 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
184 # the members of the subhashes under %filters are:
185 # callseq - a list of the parameters to the underlying filter in the
186 # order they are passed
187 # callsub - a code ref that takes a named parameter list and calls the
189 # defaults - a hash of default values
190 # names - defines names for value of given parameters so if the names
191 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
192 # foo parameter, the filter will receive 1 for the foo
195 callseq => ['image','intensity'],
196 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
200 callseq => ['image', 'amount', 'subtype'],
201 defaults => { amount=>3,subtype=>0 },
202 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
205 $filters{hardinvert} ={
206 callseq => ['image'],
208 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
211 $filters{hardinvertall} =
213 callseq => ['image'],
215 callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
218 $filters{autolevels} ={
219 callseq => ['image','lsat','usat','skew'],
220 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
221 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
224 $filters{turbnoise} ={
225 callseq => ['image'],
226 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
227 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
230 $filters{radnoise} ={
231 callseq => ['image'],
232 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
233 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
238 callseq => ['image', 'coef'],
243 i_conv($hsh{image},$hsh{coef})
244 or die Imager->_error_as_msg() . "\n";
250 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
251 defaults => { dist => 0 },
255 my @colors = @{$hsh{colors}};
258 i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
262 $filters{nearest_color} =
264 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
269 # make sure the segments are specified with colors
271 for my $color (@{$hsh{colors}}) {
272 my $new_color = _color($color)
273 or die $Imager::ERRSTR."\n";
274 push @colors, $new_color;
277 i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors,
279 or die Imager->_error_as_msg() . "\n";
282 $filters{gaussian} = {
283 callseq => [ 'image', 'stddev' ],
285 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
289 callseq => [ qw(image size) ],
290 defaults => { size => 20 },
291 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
295 callseq => [ qw(image bump elevation lightx lighty st) ],
296 defaults => { elevation=>0, st=> 2 },
299 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
300 $hsh{lightx}, $hsh{lighty}, $hsh{st});
303 $filters{bumpmap_complex} =
305 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
322 for my $cname (qw/Ia Il Is/) {
323 my $old = $hsh{$cname};
324 my $new_color = _color($old)
325 or die $Imager::ERRSTR, "\n";
326 $hsh{$cname} = $new_color;
328 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
329 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
330 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
334 $filters{postlevels} =
336 callseq => [ qw(image levels) ],
337 defaults => { levels => 10 },
338 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
340 $filters{watermark} =
342 callseq => [ qw(image wmark tx ty pixdiff) ],
343 defaults => { pixdiff=>10, tx=>0, ty=>0 },
347 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
353 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
355 ftype => { linear => 0,
361 repeat => { none => 0,
376 multiply => 2, mult => 2,
379 subtract => 5, 'sub' => 5,
389 defaults => { ftype => 0, repeat => 0, combine => 0,
390 super_sample => 0, ssample_param => 4,
403 # make sure the segments are specified with colors
405 for my $segment (@{$hsh{segments}}) {
406 my @new_segment = @$segment;
408 $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
409 push @segments, \@new_segment;
412 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
413 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
414 $hsh{ssample_param}, \@segments)
415 or die Imager->_error_as_msg() . "\n";
418 $filters{unsharpmask} =
420 callseq => [ qw(image stddev scale) ],
421 defaults => { stddev=>2.0, scale=>1.0 },
425 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
429 $FORMATGUESS=\&def_guess_type;
439 # NOTE: this might be moved to an import override later on
444 if ($_[$i] eq '-log-stderr') {
452 goto &Exporter::import;
456 Imager->open_log(log => $_[0], level => $_[1]);
461 my %parms=(loglevel=>1,@_);
463 if (exists $parms{'warn_obsolete'}) {
464 $warn_obsolete = $parms{'warn_obsolete'};
468 Imager->open_log(log => $parms{log}, level => $parms{loglevel})
472 if (exists $parms{'t1log'}) {
474 if (Imager::Font::T1::i_init_t1($parms{'t1log'})) {
475 Imager->_set_error(Imager->_error_as_msg);
489 my (%opts) = ( loglevel => 1, @_ );
491 $is_logging = i_init_log($opts{log}, $opts{loglevel});
492 unless ($is_logging) {
493 Imager->_set_error(Imager->_error_as_msg());
497 Imager->log("Imager $VERSION starting\n", 1);
503 i_init_log(undef, -1);
508 my ($class, $message, $level) = @_;
510 defined $level or $level = 1;
512 i_log_entry($message, $level);
522 print "shutdown code\n";
523 # for(keys %instances) { $instances{$_}->DESTROY(); }
524 malloc_state(); # how do decide if this should be used? -- store something from the import
525 print "Imager exiting\n";
529 # Load a filter plugin
534 my ($DSO_handle,$str)=DSO_open($filename);
535 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
536 my %funcs=DSO_funclist($DSO_handle);
537 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
539 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
541 $DSOs{$filename}=[$DSO_handle,\%funcs];
544 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
545 $DEBUG && print "eval string:\n",$evstr,"\n";
557 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
558 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
559 for(keys %{$funcref}) {
561 $DEBUG && print "unloading: $_\n";
563 my $rc=DSO_close($DSO_handle);
564 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
568 # take the results of i_error() and make a message out of it
570 return join(": ", map $_->[0], i_errors());
573 # this function tries to DWIM for color parameters
574 # color objects are used as is
575 # simple scalars are simply treated as single parameters to Imager::Color->new
576 # hashrefs are treated as named argument lists to Imager::Color->new
577 # arrayrefs are treated as list arguments to Imager::Color->new iff any
579 # other arrayrefs are treated as list arguments to Imager::Color::Float
583 # perl 5.6.0 seems to do weird things to $arg if we don't make an
584 # explicitly stringified copy
585 # I vaguely remember a bug on this on p5p, but couldn't find it
586 # through bugs.perl.org (I had trouble getting it to find any bugs)
587 my $copy = $arg . "";
591 if (UNIVERSAL::isa($arg, "Imager::Color")
592 || UNIVERSAL::isa($arg, "Imager::Color::Float")) {
596 if ($copy =~ /^HASH\(/) {
597 $result = Imager::Color->new(%$arg);
599 elsif ($copy =~ /^ARRAY\(/) {
600 $result = Imager::Color->new(@$arg);
603 $Imager::ERRSTR = "Not a color";
608 # assume Imager::Color::new knows how to handle it
609 $result = Imager::Color->new($arg);
616 my ($self, $combine, $default) = @_;
618 if (!defined $combine && ref $self) {
619 $combine = $self->{combine};
621 defined $combine or $combine = $defaults{combine};
622 defined $combine or $combine = $default;
624 if (exists $combine_types{$combine}) {
625 $combine = $combine_types{$combine};
634 $self->{IMG} and return 1;
636 $self->_set_error('empty input image');
641 # returns first defined parameter
644 return $_ if defined $_;
650 # Methods to be called on objects.
653 # Create a new Imager object takes very few parameters.
654 # usually you call this method and then call open from
655 # the resulting object
662 $self->{IMG}=undef; # Just to indicate what exists
663 $self->{ERRSTR}=undef; #
664 $self->{DEBUG}=$DEBUG;
665 $self->{DEBUG} and print "Initialized Imager\n";
666 if (defined $hsh{xsize} || defined $hsh{ysize}) {
667 unless ($self->img_set(%hsh)) {
668 $Imager::ERRSTR = $self->{ERRSTR};
672 elsif (defined $hsh{file} ||
675 defined $hsh{callback} ||
676 defined $hsh{readcb} ||
677 defined $hsh{data}) {
678 # allow $img = Imager->new(file => $filename)
681 # type is already used as a parameter to new(), rename it for the
683 if ($hsh{filetype}) {
684 $extras{type} = $hsh{filetype};
686 unless ($self->read(%hsh, %extras)) {
687 $Imager::ERRSTR = $self->{ERRSTR};
695 # Copy an entire image with no changes
696 # - if an image has magic the copy of it will not be magical
700 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
702 unless (defined wantarray) {
704 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
708 my $newcopy=Imager->new();
709 $newcopy->{IMG} = i_copy($self->{IMG});
718 unless ($self->{IMG}) {
719 $self->_set_error('empty input image');
722 my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
723 my $src = $input{img} || $input{src};
725 $self->_set_error("no source image");
728 $input{left}=0 if $input{left} <= 0;
729 $input{top}=0 if $input{top} <= 0;
731 my($r,$b)=i_img_info($src->{IMG});
732 my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
733 my ($src_right, $src_bottom);
734 if ($input{src_coords}) {
735 ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
738 if (defined $input{src_maxx}) {
739 $src_right = $input{src_maxx};
741 elsif (defined $input{width}) {
742 if ($input{width} <= 0) {
743 $self->_set_error("paste: width must me positive");
746 $src_right = $src_left + $input{width};
751 if (defined $input{src_maxy}) {
752 $src_bottom = $input{src_maxy};
754 elsif (defined $input{height}) {
755 if ($input{height} < 0) {
756 $self->_set_error("paste: height must be positive");
759 $src_bottom = $src_top + $input{height};
766 $src_right > $r and $src_right = $r;
767 $src_bottom > $b and $src_bottom = $b;
769 if ($src_right <= $src_left
770 || $src_bottom < $src_top) {
771 $self->_set_error("nothing to paste");
775 i_copyto($self->{IMG}, $src->{IMG},
776 $src_left, $src_top, $src_right, $src_bottom,
777 $input{left}, $input{top});
779 return $self; # What should go here??
782 # Crop an image - i.e. return a new image that is smaller
786 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
788 unless (defined wantarray) {
790 warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
796 my ($w, $h, $l, $r, $b, $t) =
797 @hsh{qw(width height left right bottom top)};
799 # work through the various possibilities
804 elsif (!defined $r) {
805 $r = $self->getwidth;
817 $l = int(0.5+($self->getwidth()-$w)/2);
822 $r = $self->getwidth;
828 elsif (!defined $b) {
829 $b = $self->getheight;
841 $t=int(0.5+($self->getheight()-$h)/2);
846 $b = $self->getheight;
849 ($l,$r)=($r,$l) if $l>$r;
850 ($t,$b)=($b,$t) if $t>$b;
853 $r > $self->getwidth and $r = $self->getwidth;
855 $b > $self->getheight and $b = $self->getheight;
857 if ($l == $r || $t == $b) {
858 $self->_set_error("resulting image would have no content");
861 if( $r < $l or $b < $t ) {
862 $self->_set_error("attempting to crop outside of the image");
865 my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
867 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
872 my ($self, %opts) = @_;
874 $self->{IMG} or return $self->_set_error("Not a valid image");
876 my $x = $opts{xsize} || $self->getwidth;
877 my $y = $opts{ysize} || $self->getheight;
878 my $channels = $opts{channels} || $self->getchannels;
880 my $out = Imager->new;
881 if ($channels == $self->getchannels) {
882 $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
885 $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
887 unless ($out->{IMG}) {
888 $self->{ERRSTR} = $self->_error_as_msg;
895 # Sets an image to a certain size and channel number
896 # if there was previously data in the image it is discarded
901 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
903 if (defined($self->{IMG})) {
904 # let IIM_DESTROY destroy it, it's possible this image is
905 # referenced from a virtual image (like masked)
906 #i_img_destroy($self->{IMG});
910 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
911 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
912 $hsh{maxcolors} || 256);
914 elsif ($hsh{bits} eq 'double') {
915 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
917 elsif ($hsh{bits} == 16) {
918 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
921 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
925 unless ($self->{IMG}) {
926 $self->{ERRSTR} = Imager->_error_as_msg();
933 # created a masked version of the current image
937 $self or return undef;
938 my %opts = (left => 0,
940 right => $self->getwidth,
941 bottom => $self->getheight,
943 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
945 my $result = Imager->new;
946 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
947 $opts{top}, $opts{right} - $opts{left},
948 $opts{bottom} - $opts{top});
949 unless ($result->{IMG}) {
950 $self->_set_error(Imager->_error_as_msg);
954 # keep references to the mask and base images so they don't
956 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
961 # convert an RGB image into a paletted image
965 if (@_ != 1 && !ref $_[0]) {
972 unless (defined wantarray) {
974 warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
981 my $result = Imager->new;
982 unless ($result->{IMG} = i_img_to_pal($self->{IMG}, $opts)) {
983 $self->_set_error(Imager->_error_as_msg);
991 my ($class, $quant, @images) = @_;
994 Imager->_set_error("make_palette: supply at least one image");
998 for my $img (@images) {
999 unless ($img->{IMG}) {
1000 Imager->_set_error("make_palette: image $index is empty");
1006 return i_img_make_palette($quant, map $_->{IMG}, @images);
1009 # convert a paletted (or any image) to an 8-bit/channel RGB image
1013 unless (defined wantarray) {
1014 my @caller = caller;
1015 warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
1022 my $result = Imager->new;
1023 unless ($result->{IMG} = i_img_to_rgb($self->{IMG})) {
1024 $self->_set_error(Imager->_error_as_msg());
1031 # convert a paletted (or any image) to a 16-bit/channel RGB image
1035 unless (defined wantarray) {
1036 my @caller = caller;
1037 warn "to_rgb16() called in void context - to_rgb16() returns the converted image at $caller[1] line $caller[2]\n";
1044 my $result = Imager->new;
1045 unless ($result->{IMG} = i_img_to_rgb16($self->{IMG})) {
1046 $self->_set_error(Imager->_error_as_msg());
1053 # convert a paletted (or any image) to an double/channel RGB image
1057 unless (defined wantarray) {
1058 my @caller = caller;
1059 warn "to_rgb16() called in void context - to_rgb_double() returns the converted image at $caller[1] line $caller[2]\n";
1066 my $result = Imager->new;
1067 unless ($result->{IMG} = i_img_to_drgb($self->{IMG})) {
1068 $self->_set_error(Imager->_error_as_msg());
1077 my %opts = (colors=>[], @_);
1079 unless ($self->{IMG}) {
1080 $self->_set_error("empty input image");
1084 my @colors = @{$opts{colors}}
1087 for my $color (@colors) {
1088 $color = _color($color);
1090 $self->_set_error($Imager::ERRSTR);
1095 return i_addcolors($self->{IMG}, @colors);
1100 my %opts = (start=>0, colors=>[], @_);
1102 unless ($self->{IMG}) {
1103 $self->_set_error("empty input image");
1107 my @colors = @{$opts{colors}}
1110 for my $color (@colors) {
1111 $color = _color($color);
1113 $self->_set_error($Imager::ERRSTR);
1118 return i_setcolors($self->{IMG}, $opts{start}, @colors);
1124 if (!exists $opts{start} && !exists $opts{count}) {
1127 $opts{count} = $self->colorcount;
1129 elsif (!exists $opts{count}) {
1132 elsif (!exists $opts{start}) {
1137 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
1141 i_colorcount($_[0]{IMG});
1145 i_maxcolors($_[0]{IMG});
1151 $opts{color} or return undef;
1153 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
1158 my $bits = $self->{IMG} && i_img_bits($self->{IMG});
1159 if ($bits && $bits == length(pack("d", 1)) * 8) {
1168 return i_img_type($self->{IMG}) ? "paletted" : "direct";
1174 $self->{IMG} and i_img_virtual($self->{IMG});
1180 $self->{IMG} or return;
1182 return i_img_is_monochrome($self->{IMG});
1186 my ($self, %opts) = @_;
1188 $self->{IMG} or return;
1190 if (defined $opts{name}) {
1194 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
1195 push @result, (i_tags_get($self->{IMG}, $found))[1];
1198 return wantarray ? @result : $result[0];
1200 elsif (defined $opts{code}) {
1204 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
1205 push @result, (i_tags_get($self->{IMG}, $found))[1];
1212 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
1215 return i_tags_count($self->{IMG});
1224 return -1 unless $self->{IMG};
1226 if (defined $opts{value}) {
1227 if ($opts{value} =~ /^\d+$/) {
1229 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
1232 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
1235 elsif (defined $opts{data}) {
1236 # force addition as a string
1237 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
1240 $self->{ERRSTR} = "No value supplied";
1244 elsif ($opts{code}) {
1245 if (defined $opts{value}) {
1246 if ($opts{value} =~ /^\d+$/) {
1248 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
1251 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
1254 elsif (defined $opts{data}) {
1255 # force addition as a string
1256 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
1259 $self->{ERRSTR} = "No value supplied";
1272 return 0 unless $self->{IMG};
1274 if (defined $opts{'index'}) {
1275 return i_tags_delete($self->{IMG}, $opts{'index'});
1277 elsif (defined $opts{name}) {
1278 return i_tags_delbyname($self->{IMG}, $opts{name});
1280 elsif (defined $opts{code}) {
1281 return i_tags_delbycode($self->{IMG}, $opts{code});
1284 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
1290 my ($self, %opts) = @_;
1293 $self->deltag(name=>$opts{name});
1294 return $self->addtag(name=>$opts{name}, value=>$opts{value});
1296 elsif (defined $opts{code}) {
1297 $self->deltag(code=>$opts{code});
1298 return $self->addtag(code=>$opts{code}, value=>$opts{value});
1306 sub _get_reader_io {
1307 my ($self, $input) = @_;
1310 return $input->{io}, undef;
1312 elsif ($input->{fd}) {
1313 return io_new_fd($input->{fd});
1315 elsif ($input->{fh}) {
1316 my $fd = fileno($input->{fh});
1317 unless (defined $fd) {
1318 $self->_set_error("Handle in fh option not opened");
1321 return io_new_fd($fd);
1323 elsif ($input->{file}) {
1324 my $file = IO::File->new($input->{file}, "r");
1326 $self->_set_error("Could not open $input->{file}: $!");
1330 return (io_new_fd(fileno($file)), $file);
1332 elsif ($input->{data}) {
1333 return io_new_buffer($input->{data});
1335 elsif ($input->{callback} || $input->{readcb}) {
1336 if (!$input->{seekcb}) {
1337 $self->_set_error("Need a seekcb parameter");
1339 if ($input->{maxbuffer}) {
1340 return io_new_cb($input->{writecb},
1341 $input->{callback} || $input->{readcb},
1342 $input->{seekcb}, $input->{closecb},
1343 $input->{maxbuffer});
1346 return io_new_cb($input->{writecb},
1347 $input->{callback} || $input->{readcb},
1348 $input->{seekcb}, $input->{closecb});
1352 $self->_set_error("file/fd/fh/data/callback parameter missing");
1357 sub _get_writer_io {
1358 my ($self, $input) = @_;
1360 my $buffered = exists $input->{buffered} ? $input->{buffered} : 1;
1367 elsif ($input->{fd}) {
1368 $io = io_new_fd($input->{fd});
1370 elsif ($input->{fh}) {
1371 my $fd = fileno($input->{fh});
1372 unless (defined $fd) {
1373 $self->_set_error("Handle in fh option not opened");
1377 my $oldfh = select($input->{fh});
1378 # flush anything that's buffered, and make sure anything else is flushed
1381 $io = io_new_fd($fd);
1383 elsif ($input->{file}) {
1384 my $fh = new IO::File($input->{file},"w+");
1386 $self->_set_error("Could not open file $input->{file}: $!");
1389 binmode($fh) or die;
1390 $io = io_new_fd(fileno($fh));
1393 elsif ($input->{data}) {
1394 $io = io_new_bufchain();
1396 elsif ($input->{callback} || $input->{writecb}) {
1397 if ($input->{maxbuffer} && $input->{maxbuffer} == 1) {
1400 $io = io_new_cb($input->{callback} || $input->{writecb},
1402 $input->{seekcb}, $input->{closecb});
1405 $self->_set_error("file/fd/fh/data/callback parameter missing");
1409 unless ($buffered) {
1410 $io->set_buffered(0);
1413 return ($io, @extras);
1416 # Read an image from file
1422 if (defined($self->{IMG})) {
1423 # let IIM_DESTROY do the destruction, since the image may be
1424 # referenced from elsewhere
1425 #i_img_destroy($self->{IMG});
1426 undef($self->{IMG});
1429 my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
1431 my $type = $input{'type'};
1433 $type = i_test_format_probe($IO, -1);
1436 if ($input{file} && !$type) {
1438 $type = $FORMATGUESS->($input{file});
1442 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1443 $input{file} and $msg .= " or file name";
1444 $self->_set_error($msg);
1448 _reader_autoload($type);
1450 if ($readers{$type} && $readers{$type}{single}) {
1451 return $readers{$type}{single}->($self, $IO, %input);
1454 unless ($formats_low{$type}) {
1455 my $read_types = join ', ', sort Imager->read_types();
1456 $self->_set_error("format '$type' not supported - formats $read_types available for reading - $reader_load_errors{$type}");
1460 my $allow_incomplete = $input{allow_incomplete};
1461 defined $allow_incomplete or $allow_incomplete = 0;
1463 if ( $type eq 'pnm' ) {
1464 $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
1465 if ( !defined($self->{IMG}) ) {
1466 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
1469 $self->{DEBUG} && print "loading a pnm file\n";
1473 if ( $type eq 'bmp' ) {
1474 $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
1475 if ( !defined($self->{IMG}) ) {
1476 $self->{ERRSTR}=$self->_error_as_msg();
1479 $self->{DEBUG} && print "loading a bmp file\n";
1482 if ( $type eq 'tga' ) {
1483 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
1484 if ( !defined($self->{IMG}) ) {
1485 $self->{ERRSTR}=$self->_error_as_msg();
1488 $self->{DEBUG} && print "loading a tga file\n";
1491 if ( $type eq 'raw' ) {
1492 unless ( $input{xsize} && $input{ysize} ) {
1493 $self->_set_error('missing xsize or ysize parameter for raw');
1497 my $interleave = _first($input{raw_interleave}, $input{interleave});
1498 unless (defined $interleave) {
1499 my @caller = caller;
1500 warn "read(type => 'raw') $caller[2] line $caller[1]: supply interleave or raw_interleave for future compatibility\n";
1503 my $data_ch = _first($input{raw_datachannels}, $input{datachannels}, 3);
1504 my $store_ch = _first($input{raw_storechannels}, $input{storechannels}, 3);
1506 $self->{IMG} = i_readraw_wiol( $IO,
1512 if ( !defined($self->{IMG}) ) {
1513 $self->{ERRSTR}=$self->_error_as_msg();
1516 $self->{DEBUG} && print "loading a raw file\n";
1522 sub register_reader {
1523 my ($class, %opts) = @_;
1526 or die "register_reader called with no type parameter\n";
1528 my $type = $opts{type};
1530 defined $opts{single} || defined $opts{multiple}
1531 or die "register_reader called with no single or multiple parameter\n";
1533 $readers{$type} = { };
1534 if ($opts{single}) {
1535 $readers{$type}{single} = $opts{single};
1537 if ($opts{multiple}) {
1538 $readers{$type}{multiple} = $opts{multiple};
1544 sub register_writer {
1545 my ($class, %opts) = @_;
1548 or die "register_writer called with no type parameter\n";
1550 my $type = $opts{type};
1552 defined $opts{single} || defined $opts{multiple}
1553 or die "register_writer called with no single or multiple parameter\n";
1555 $writers{$type} = { };
1556 if ($opts{single}) {
1557 $writers{$type}{single} = $opts{single};
1559 if ($opts{multiple}) {
1560 $writers{$type}{multiple} = $opts{multiple};
1571 grep($file_formats{$_}, keys %formats),
1572 qw(ico sgi), # formats not handled directly, but supplied with Imager
1583 grep($file_formats{$_}, keys %formats),
1584 qw(ico sgi), # formats not handled directly, but supplied with Imager
1591 my ($file, $error) = @_;
1593 if ($attempted_to_load{$file}) {
1594 if ($file_load_errors{$file}) {
1595 $$error = $file_load_errors{$file};
1603 local $SIG{__DIE__};
1605 ++$attempted_to_load{$file};
1613 my $work = $@ || "Unknown error loading $file";
1615 $work =~ s/\n?Compilation failed in require at .*Imager\.pm line .*\z//m;
1616 $work =~ s/\n/\\n/g;
1617 $file_load_errors{$file} = $work;
1624 # probes for an Imager::File::whatever module
1625 sub _reader_autoload {
1628 return if $formats_low{$type} || $readers{$type};
1630 return unless $type =~ /^\w+$/;
1632 my $file = "Imager/File/\U$type\E.pm";
1635 my $loaded = _load_file($file, \$error);
1636 if (!$loaded && $error =~ /^Can't locate /) {
1637 my $filer = "Imager/File/\U$type\EReader.pm";
1638 $loaded = _load_file($filer, \$error);
1639 if ($error =~ /^Can't locate /) {
1640 $error = "Can't locate $file or $filer";
1644 $reader_load_errors{$type} = $error;
1648 # probes for an Imager::File::whatever module
1649 sub _writer_autoload {
1652 return if $formats_low{$type} || $writers{$type};
1654 return unless $type =~ /^\w+$/;
1656 my $file = "Imager/File/\U$type\E.pm";
1659 my $loaded = _load_file($file, \$error);
1660 if (!$loaded && $error =~ /^Can't locate /) {
1661 my $filew = "Imager/File/\U$type\EWriter.pm";
1662 $loaded = _load_file($filew, \$error);
1663 if ($error =~ /^Can't locate /) {
1664 $error = "Can't locate $file or $filew";
1668 $writer_load_errors{$type} = $error;
1672 sub _fix_gif_positions {
1673 my ($opts, $opt, $msg, @imgs) = @_;
1675 my $positions = $opts->{'gif_positions'};
1677 for my $pos (@$positions) {
1678 my ($x, $y) = @$pos;
1679 my $img = $imgs[$index++];
1680 $img->settag(name=>'gif_left', value=>$x);
1681 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1683 $$msg .= "replaced with the gif_left and gif_top tags";
1688 gif_each_palette=>'gif_local_map',
1689 interlace => 'gif_interlace',
1690 gif_delays => 'gif_delay',
1691 gif_positions => \&_fix_gif_positions,
1692 gif_loop_count => 'gif_loop',
1695 # options that should be converted to colors
1696 my %color_opts = map { $_ => 1 } qw/i_background/;
1699 my ($self, $opts, $prefix, @imgs) = @_;
1701 for my $opt (keys %$opts) {
1703 if ($obsolete_opts{$opt}) {
1704 my $new = $obsolete_opts{$opt};
1705 my $msg = "Obsolete option $opt ";
1707 $new->($opts, $opt, \$msg, @imgs);
1710 $msg .= "replaced with the $new tag ";
1713 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1714 warn $msg if $warn_obsolete && $^W;
1716 next unless $tagname =~ /^\Q$prefix/;
1717 my $value = $opts->{$opt};
1718 if ($color_opts{$opt}) {
1719 $value = _color($value);
1721 $self->_set_error($Imager::ERRSTR);
1726 if (UNIVERSAL::isa($value, "Imager::Color")) {
1727 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1728 for my $img (@imgs) {
1729 $img->settag(name=>$tagname, value=>$tag);
1732 elsif (ref($value) eq 'ARRAY') {
1733 for my $i (0..$#$value) {
1734 my $val = $value->[$i];
1736 if (UNIVERSAL::isa($val, "Imager::Color")) {
1737 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1739 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1742 $self->_set_error("Unknown reference type " . ref($value) .
1743 " supplied in array for $opt");
1749 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1754 $self->_set_error("Unknown reference type " . ref($value) .
1755 " supplied for $opt");
1760 # set it as a tag for every image
1761 for my $img (@imgs) {
1762 $img->settag(name=>$tagname, value=>$value);
1770 # Write an image to file
1773 my %input=(jpegquality=>75,
1783 $self->_set_opts(\%input, "i_", $self)
1786 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1788 my $type = $input{'type'};
1789 if (!$type and $input{file}) {
1790 $type = $FORMATGUESS->($input{file});
1793 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1797 _writer_autoload($type);
1800 if ($writers{$type} && $writers{$type}{single}) {
1801 ($IO, $fh) = $self->_get_writer_io(\%input)
1804 $writers{$type}{single}->($self, $IO, %input, type => $type)
1808 if (!$formats_low{$type}) {
1809 my $write_types = join ', ', sort Imager->write_types();
1810 $self->_set_error("format '$type' not supported - formats $write_types available for writing - $writer_load_errors{$type}");
1814 ($IO, $fh) = $self->_get_writer_io(\%input, $type)
1817 if ( $type eq 'pnm' ) {
1818 $self->_set_opts(\%input, "pnm_", $self)
1820 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1821 $self->{ERRSTR} = $self->_error_as_msg();
1824 $self->{DEBUG} && print "writing a pnm file\n";
1826 elsif ( $type eq 'raw' ) {
1827 $self->_set_opts(\%input, "raw_", $self)
1829 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1830 $self->{ERRSTR} = $self->_error_as_msg();
1833 $self->{DEBUG} && print "writing a raw file\n";
1835 elsif ( $type eq 'bmp' ) {
1836 $self->_set_opts(\%input, "bmp_", $self)
1838 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1839 $self->{ERRSTR} = $self->_error_as_msg;
1842 $self->{DEBUG} && print "writing a bmp file\n";
1844 elsif ( $type eq 'tga' ) {
1845 $self->_set_opts(\%input, "tga_", $self)
1848 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1849 $self->{ERRSTR}=$self->_error_as_msg();
1852 $self->{DEBUG} && print "writing a tga file\n";
1856 if (exists $input{'data'}) {
1857 my $data = io_slurp($IO);
1859 $self->{ERRSTR}='Could not slurp from buffer';
1862 ${$input{data}} = $data;
1868 my ($class, $opts, @images) = @_;
1870 my $type = $opts->{type};
1872 if (!$type && $opts->{'file'}) {
1873 $type = $FORMATGUESS->($opts->{'file'});
1876 $class->_set_error('type parameter missing and not possible to guess from extension');
1879 # translate to ImgRaw
1880 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1881 $class->_set_error('Usage: Imager->write_multi({ options }, @images)');
1884 $class->_set_opts($opts, "i_", @images)
1886 my @work = map $_->{IMG}, @images;
1888 _writer_autoload($type);
1891 if ($writers{$type} && $writers{$type}{multiple}) {
1892 ($IO, $file) = $class->_get_writer_io($opts, $type)
1895 $writers{$type}{multiple}->($class, $IO, $opts, @images)
1899 if (!$formats{$type}) {
1900 my $write_types = join ', ', sort Imager->write_types();
1901 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
1905 ($IO, $file) = $class->_get_writer_io($opts, $type)
1908 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
1912 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
1917 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
1923 if (exists $opts->{'data'}) {
1924 my $data = io_slurp($IO);
1926 Imager->_set_error('Could not slurp from buffer');
1929 ${$opts->{data}} = $data;
1934 # read multiple images from a file
1936 my ($class, %opts) = @_;
1938 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
1941 my $type = $opts{'type'};
1943 $type = i_test_format_probe($IO, -1);
1946 if ($opts{file} && !$type) {
1948 $type = $FORMATGUESS->($opts{file});
1952 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1953 $opts{file} and $msg .= " or file name";
1954 Imager->_set_error($msg);
1958 _reader_autoload($type);
1960 if ($readers{$type} && $readers{$type}{multiple}) {
1961 return $readers{$type}{multiple}->($IO, %opts);
1964 unless ($formats{$type}) {
1965 my $read_types = join ', ', sort Imager->read_types();
1966 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
1971 if ($type eq 'pnm') {
1972 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
1975 my $img = Imager->new;
1976 if ($img->read(%opts, io => $IO, type => $type)) {
1979 Imager->_set_error($img->errstr);
1984 $ERRSTR = _error_as_msg();
1988 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1992 # Destroy an Imager object
1996 # delete $instances{$self};
1997 if (defined($self->{IMG})) {
1998 # the following is now handled by the XS DESTROY method for
1999 # Imager::ImgRaw object
2000 # Re-enabling this will break virtual images
2001 # tested for in t/t020masked.t
2002 # i_img_destroy($self->{IMG});
2003 undef($self->{IMG});
2005 # print "Destroy Called on an empty image!\n"; # why did I put this here??
2009 # Perform an inplace filter of an image
2010 # that is the image will be overwritten with the data
2016 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2018 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
2020 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
2021 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
2024 if ($filters{$input{'type'}}{names}) {
2025 my $names = $filters{$input{'type'}}{names};
2026 for my $name (keys %$names) {
2027 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
2028 $input{$name} = $names->{$name}{$input{$name}};
2032 if (defined($filters{$input{'type'}}{defaults})) {
2033 %hsh=( image => $self->{IMG},
2035 %{$filters{$input{'type'}}{defaults}},
2038 %hsh=( image => $self->{IMG},
2043 my @cs=@{$filters{$input{'type'}}{callseq}};
2046 if (!defined($hsh{$_})) {
2047 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
2052 local $SIG{__DIE__}; # we don't want this processed by confess, etc
2053 &{$filters{$input{'type'}}{callsub}}(%hsh);
2056 chomp($self->{ERRSTR} = $@);
2062 $self->{DEBUG} && print "callseq is: @cs\n";
2063 $self->{DEBUG} && print "matching callseq is: @b\n";
2068 sub register_filter {
2070 my %hsh = ( defaults => {}, @_ );
2073 or die "register_filter() with no type\n";
2074 defined $hsh{callsub}
2075 or die "register_filter() with no callsub\n";
2076 defined $hsh{callseq}
2077 or die "register_filter() with no callseq\n";
2079 exists $filters{$hsh{type}}
2082 $filters{$hsh{type}} = \%hsh;
2087 sub scale_calculate {
2090 my %opts = ('type'=>'max', @_);
2092 # none of these should be references
2093 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2094 if (defined $opts{$name} && ref $opts{$name}) {
2095 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2100 my ($x_scale, $y_scale);
2101 my $width = $opts{width};
2102 my $height = $opts{height};
2104 defined $width or $width = $self->getwidth;
2105 defined $height or $height = $self->getheight;
2108 unless (defined $width && defined $height) {
2109 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2114 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2115 $x_scale = $opts{'xscalefactor'};
2116 $y_scale = $opts{'yscalefactor'};
2118 elsif ($opts{'xscalefactor'}) {
2119 $x_scale = $opts{'xscalefactor'};
2120 $y_scale = $opts{'scalefactor'} || $x_scale;
2122 elsif ($opts{'yscalefactor'}) {
2123 $y_scale = $opts{'yscalefactor'};
2124 $x_scale = $opts{'scalefactor'} || $y_scale;
2127 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2130 # work out the scaling
2131 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2132 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2133 $opts{ypixels} / $height );
2134 if ($opts{'type'} eq 'min') {
2135 $x_scale = $y_scale = _min($xpix,$ypix);
2137 elsif ($opts{'type'} eq 'max') {
2138 $x_scale = $y_scale = _max($xpix,$ypix);
2140 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2145 $self->_set_error('invalid value for type parameter');
2148 } elsif ($opts{xpixels}) {
2149 $x_scale = $y_scale = $opts{xpixels} / $width;
2151 elsif ($opts{ypixels}) {
2152 $x_scale = $y_scale = $opts{ypixels}/$height;
2154 elsif ($opts{constrain} && ref $opts{constrain}
2155 && $opts{constrain}->can('constrain')) {
2156 # we've been passed an Image::Math::Constrain object or something
2157 # that looks like one
2159 (undef, undef, $scalefactor)
2160 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2161 unless ($scalefactor) {
2162 $self->_set_error('constrain method failed on constrain parameter');
2165 $x_scale = $y_scale = $scalefactor;
2168 my $new_width = int($x_scale * $width + 0.5);
2169 $new_width > 0 or $new_width = 1;
2170 my $new_height = int($y_scale * $height + 0.5);
2171 $new_height > 0 or $new_height = 1;
2173 return ($x_scale, $y_scale, $new_width, $new_height);
2177 # Scale an image to requested size and return the scaled version
2181 my %opts = (qtype=>'normal' ,@_);
2182 my $img = Imager->new();
2183 my $tmp = Imager->new();
2185 unless (defined wantarray) {
2186 my @caller = caller;
2187 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2191 unless ($self->{IMG}) {
2192 $self->_set_error('empty input image');
2196 my ($x_scale, $y_scale, $new_width, $new_height) =
2197 $self->scale_calculate(%opts)
2200 if ($opts{qtype} eq 'normal') {
2201 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2202 if ( !defined($tmp->{IMG}) ) {
2203 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2206 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2207 if ( !defined($img->{IMG}) ) {
2208 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2214 elsif ($opts{'qtype'} eq 'preview') {
2215 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2216 if ( !defined($img->{IMG}) ) {
2217 $self->{ERRSTR}='unable to scale image';
2222 elsif ($opts{'qtype'} eq 'mixing') {
2223 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2224 unless ($img->{IMG}) {
2225 $self->_set_error(Imager->_error_as_msg);
2231 $self->_set_error('invalid value for qtype parameter');
2236 # Scales only along the X axis
2240 my %opts = ( scalefactor=>0.5, @_ );
2242 unless (defined wantarray) {
2243 my @caller = caller;
2244 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2248 unless ($self->{IMG}) {
2249 $self->{ERRSTR} = 'empty input image';
2253 my $img = Imager->new();
2255 my $scalefactor = $opts{scalefactor};
2257 if ($opts{pixels}) {
2258 $scalefactor = $opts{pixels} / $self->getwidth();
2261 unless ($self->{IMG}) {
2262 $self->{ERRSTR}='empty input image';
2266 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2268 if ( !defined($img->{IMG}) ) {
2269 $self->{ERRSTR} = 'unable to scale image';
2276 # Scales only along the Y axis
2280 my %opts = ( scalefactor => 0.5, @_ );
2282 unless (defined wantarray) {
2283 my @caller = caller;
2284 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2288 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2290 my $img = Imager->new();
2292 my $scalefactor = $opts{scalefactor};
2294 if ($opts{pixels}) {
2295 $scalefactor = $opts{pixels} / $self->getheight();
2298 unless ($self->{IMG}) {
2299 $self->{ERRSTR} = 'empty input image';
2302 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2304 if ( !defined($img->{IMG}) ) {
2305 $self->{ERRSTR} = 'unable to scale image';
2312 # Transform returns a spatial transformation of the input image
2313 # this moves pixels to a new location in the returned image.
2314 # NOTE - should make a utility function to check transforms for
2319 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2321 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2323 # print Dumper(\%opts);
2326 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2328 eval ("use Affix::Infix2Postfix;");
2331 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2334 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2335 {op=>'-',trans=>'Sub'},
2336 {op=>'*',trans=>'Mult'},
2337 {op=>'/',trans=>'Div'},
2338 {op=>'-','type'=>'unary',trans=>'u-'},
2340 {op=>'func','type'=>'unary'}],
2341 'grouping'=>[qw( \( \) )],
2342 'func'=>[qw( sin cos )],
2347 @xt=$I2P->translate($opts{'xexpr'});
2348 @yt=$I2P->translate($opts{'yexpr'});
2350 $numre=$I2P->{'numre'};
2353 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2354 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2355 @{$opts{'parm'}}=@pt;
2358 # print Dumper(\%opts);
2360 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2361 $self->{ERRSTR}='transform: no xopcodes given.';
2365 @op=@{$opts{'xopcodes'}};
2367 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2368 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2371 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2377 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2378 $self->{ERRSTR}='transform: no yopcodes given.';
2382 @op=@{$opts{'yopcodes'}};
2384 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2385 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2388 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2393 if ( !exists $opts{'parm'}) {
2394 $self->{ERRSTR}='transform: no parameter arg given.';
2398 # print Dumper(\@ropx);
2399 # print Dumper(\@ropy);
2400 # print Dumper(\@ropy);
2402 my $img = Imager->new();
2403 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2404 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2410 my ($opts, @imgs) = @_;
2412 require "Imager/Expr.pm";
2414 $opts->{variables} = [ qw(x y) ];
2415 my ($width, $height) = @{$opts}{qw(width height)};
2417 $width ||= $imgs[0]->getwidth();
2418 $height ||= $imgs[0]->getheight();
2420 for my $img (@imgs) {
2421 $opts->{constants}{"w$img_num"} = $img->getwidth();
2422 $opts->{constants}{"h$img_num"} = $img->getheight();
2423 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2424 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2429 $opts->{constants}{w} = $width;
2430 $opts->{constants}{cx} = $width/2;
2433 $Imager::ERRSTR = "No width supplied";
2437 $opts->{constants}{h} = $height;
2438 $opts->{constants}{cy} = $height/2;
2441 $Imager::ERRSTR = "No height supplied";
2444 my $code = Imager::Expr->new($opts);
2446 $Imager::ERRSTR = Imager::Expr::error();
2449 my $channels = $opts->{channels} || 3;
2450 unless ($channels >= 1 && $channels <= 4) {
2451 return Imager->_set_error("channels must be an integer between 1 and 4");
2454 my $img = Imager->new();
2455 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2456 $channels, $code->code(),
2457 $code->nregs(), $code->cregs(),
2458 [ map { $_->{IMG} } @imgs ]);
2459 if (!defined $img->{IMG}) {
2460 $Imager::ERRSTR = Imager->_error_as_msg();
2471 unless ($self->{IMG}) {
2472 $self->{ERRSTR}='empty input image';
2475 unless ($opts{src} && $opts{src}->{IMG}) {
2476 $self->{ERRSTR}='empty input image for src';
2480 %opts = (src_minx => 0,
2482 src_maxx => $opts{src}->getwidth(),
2483 src_maxy => $opts{src}->getheight(),
2487 defined $tx or $tx = $opts{left};
2488 defined $tx or $tx = 0;
2491 defined $ty or $ty = $opts{top};
2492 defined $ty or $ty = 0;
2494 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2495 $opts{src_minx}, $opts{src_miny},
2496 $opts{src_maxx}, $opts{src_maxy})) {
2497 $self->_set_error($self->_error_as_msg());
2514 unless ($self->{IMG}) {
2515 $self->_set_error("compose: empty input image");
2519 unless ($opts{src}) {
2520 $self->_set_error("compose: src parameter missing");
2524 unless ($opts{src}{IMG}) {
2525 $self->_set_error("compose: src parameter empty image");
2528 my $src = $opts{src};
2530 my $left = $opts{left};
2531 defined $left or $left = $opts{tx};
2532 defined $left or $left = 0;
2534 my $top = $opts{top};
2535 defined $top or $top = $opts{ty};
2536 defined $top or $top = 0;
2538 my $src_left = $opts{src_left};
2539 defined $src_left or $src_left = $opts{src_minx};
2540 defined $src_left or $src_left = 0;
2542 my $src_top = $opts{src_top};
2543 defined $src_top or $src_top = $opts{src_miny};
2544 defined $src_top or $src_top = 0;
2546 my $width = $opts{width};
2547 if (!defined $width && defined $opts{src_maxx}) {
2548 $width = $opts{src_maxx} - $src_left;
2550 defined $width or $width = $src->getwidth() - $src_left;
2552 my $height = $opts{height};
2553 if (!defined $height && defined $opts{src_maxy}) {
2554 $height = $opts{src_maxy} - $src_top;
2556 defined $height or $height = $src->getheight() - $src_top;
2558 my $combine = $self->_combine($opts{combine}, 'normal');
2561 unless ($opts{mask}{IMG}) {
2562 $self->_set_error("compose: mask parameter empty image");
2566 my $mask_left = $opts{mask_left};
2567 defined $mask_left or $mask_left = $opts{mask_minx};
2568 defined $mask_left or $mask_left = 0;
2570 my $mask_top = $opts{mask_top};
2571 defined $mask_top or $mask_top = $opts{mask_miny};
2572 defined $mask_top or $mask_top = 0;
2574 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2575 $left, $top, $src_left, $src_top,
2576 $mask_left, $mask_top, $width, $height,
2577 $combine, $opts{opacity})) {
2578 $self->_set_error(Imager->_error_as_msg);
2583 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2584 $width, $height, $combine, $opts{opacity})) {
2585 $self->_set_error(Imager->_error_as_msg);
2596 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2598 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2599 $dir = $xlate{$opts{'dir'}};
2600 return $self if i_flipxy($self->{IMG}, $dir);
2608 unless (defined wantarray) {
2609 my @caller = caller;
2610 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2614 if (defined $opts{right}) {
2615 my $degrees = $opts{right};
2617 $degrees += 360 * int(((-$degrees)+360)/360);
2619 $degrees = $degrees % 360;
2620 if ($degrees == 0) {
2621 return $self->copy();
2623 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2624 my $result = Imager->new();
2625 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2629 $self->{ERRSTR} = $self->_error_as_msg();
2634 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2638 elsif (defined $opts{radians} || defined $opts{degrees}) {
2639 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
2641 my $back = $opts{back};
2642 my $result = Imager->new;
2644 $back = _color($back);
2646 $self->_set_error(Imager->errstr);
2650 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2653 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2655 if ($result->{IMG}) {
2659 $self->{ERRSTR} = $self->_error_as_msg();
2664 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2669 sub matrix_transform {
2673 unless (defined wantarray) {
2674 my @caller = caller;
2675 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2679 if ($opts{matrix}) {
2680 my $xsize = $opts{xsize} || $self->getwidth;
2681 my $ysize = $opts{ysize} || $self->getheight;
2683 my $result = Imager->new;
2685 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2686 $opts{matrix}, $opts{back})
2690 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2698 $self->{ERRSTR} = "matrix parameter required";
2704 *yatf = \&matrix_transform;
2706 # These two are supported for legacy code only
2709 return Imager::Color->new(@_);
2713 return Imager::Color::set(@_);
2716 # Draws a box between the specified corner points.
2719 my $raw = $self->{IMG};
2722 $self->{ERRSTR}='empty input image';
2728 my ($xmin, $ymin, $xmax, $ymax);
2729 if (exists $opts{'box'}) {
2730 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2731 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2732 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2733 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2736 defined($xmin = $opts{xmin}) or $xmin = 0;
2737 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2738 defined($ymin = $opts{ymin}) or $ymin = 0;
2739 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2742 if ($opts{filled}) {
2743 my $color = $opts{'color'};
2745 if (defined $color) {
2746 unless (_is_color_object($color)) {
2747 $color = _color($color);
2749 $self->{ERRSTR} = $Imager::ERRSTR;
2755 $color = i_color_new(255,255,255,255);
2758 if ($color->isa("Imager::Color")) {
2759 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2762 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2765 elsif ($opts{fill}) {
2766 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2767 # assume it's a hash ref
2768 require 'Imager/Fill.pm';
2769 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2770 $self->{ERRSTR} = $Imager::ERRSTR;
2774 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2777 my $color = $opts{'color'};
2778 if (defined $color) {
2779 unless (_is_color_object($color)) {
2780 $color = _color($color);
2782 $self->{ERRSTR} = $Imager::ERRSTR;
2788 $color = i_color_new(255, 255, 255, 255);
2791 $self->{ERRSTR} = $Imager::ERRSTR;
2794 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2802 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2803 my $dflcl= [ 255, 255, 255, 255];
2808 'r'=>_min($self->getwidth(),$self->getheight())/3,
2809 'x'=>$self->getwidth()/2,
2810 'y'=>$self->getheight()/2,
2817 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2818 # assume it's a hash ref
2819 require 'Imager/Fill.pm';
2820 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2821 $self->{ERRSTR} = $Imager::ERRSTR;
2825 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2826 $opts{'d2'}, $opts{fill}{fill});
2828 elsif ($opts{filled}) {
2829 my $color = _color($opts{'color'});
2831 $self->{ERRSTR} = $Imager::ERRSTR;
2834 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2835 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2839 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2840 $opts{'d1'}, $opts{'d2'}, $color);
2844 my $color = _color($opts{'color'});
2845 if ($opts{d2} - $opts{d1} >= 360) {
2846 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
2849 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
2855 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2856 # assume it's a hash ref
2857 require 'Imager/Fill.pm';
2858 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2859 $self->{ERRSTR} = $Imager::ERRSTR;
2863 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2864 $opts{'d2'}, $opts{fill}{fill});
2867 my $color = _color($opts{'color'});
2869 $self->{ERRSTR} = $Imager::ERRSTR;
2872 if ($opts{filled}) {
2873 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2874 $opts{'d1'}, $opts{'d2'}, $color);
2877 if ($opts{d1} == 0 && $opts{d2} == 361) {
2878 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
2881 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
2887 $self->_set_error($self->_error_as_msg);
2894 # Draws a line from one point to the other
2895 # the endpoint is set if the endp parameter is set which it is by default.
2896 # to turn of the endpoint being set use endp=>0 when calling line.
2900 my $dflcl=i_color_new(0,0,0,0);
2901 my %opts=(color=>$dflcl,
2904 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2906 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
2907 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
2909 my $color = _color($opts{'color'});
2911 $self->{ERRSTR} = $Imager::ERRSTR;
2915 $opts{antialias} = $opts{aa} if defined $opts{aa};
2916 if ($opts{antialias}) {
2917 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2918 $color, $opts{endp});
2920 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2921 $color, $opts{endp});
2926 # Draws a line between an ordered set of points - It more or less just transforms this
2927 # into a list of lines.
2931 my ($pt,$ls,@points);
2932 my $dflcl=i_color_new(0,0,0,0);
2933 my %opts=(color=>$dflcl,@_);
2935 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2937 if (exists($opts{points})) { @points=@{$opts{points}}; }
2938 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
2939 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
2942 # print Dumper(\@points);
2944 my $color = _color($opts{'color'});
2946 $self->{ERRSTR} = $Imager::ERRSTR;
2949 $opts{antialias} = $opts{aa} if defined $opts{aa};
2950 if ($opts{antialias}) {
2953 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
2960 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
2970 my ($pt,$ls,@points);
2971 my $dflcl = i_color_new(0,0,0,0);
2972 my %opts = (color=>$dflcl, @_);
2974 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2976 if (exists($opts{points})) {
2977 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
2978 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
2981 if (!exists $opts{'x'} or !exists $opts{'y'}) {
2982 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
2985 if ($opts{'fill'}) {
2986 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
2987 # assume it's a hash ref
2988 require 'Imager/Fill.pm';
2989 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
2990 $self->{ERRSTR} = $Imager::ERRSTR;
2994 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
2995 $opts{'fill'}{'fill'});
2998 my $color = _color($opts{'color'});
3000 $self->{ERRSTR} = $Imager::ERRSTR;
3003 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3010 # this the multipoint bezier curve
3011 # this is here more for testing that actual usage since
3012 # this is not a good algorithm. Usually the curve would be
3013 # broken into smaller segments and each done individually.
3017 my ($pt,$ls,@points);
3018 my $dflcl=i_color_new(0,0,0,0);
3019 my %opts=(color=>$dflcl,@_);
3021 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3023 if (exists $opts{points}) {
3024 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
3025 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
3028 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
3029 $self->{ERRSTR}='Missing or invalid points.';
3033 my $color = _color($opts{'color'});
3035 $self->{ERRSTR} = $Imager::ERRSTR;
3038 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
3044 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
3047 unless (exists $opts{'x'} && exists $opts{'y'}) {
3048 $self->{ERRSTR} = "missing seed x and y parameters";
3052 if ($opts{border}) {
3053 my $border = _color($opts{border});
3055 $self->_set_error($Imager::ERRSTR);
3059 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3060 # assume it's a hash ref
3061 require Imager::Fill;
3062 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3063 $self->{ERRSTR} = $Imager::ERRSTR;
3067 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3068 $opts{fill}{fill}, $border);
3071 my $color = _color($opts{'color'});
3073 $self->{ERRSTR} = $Imager::ERRSTR;
3076 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3083 $self->{ERRSTR} = $self->_error_as_msg();
3089 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3090 # assume it's a hash ref
3091 require 'Imager/Fill.pm';
3092 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3093 $self->{ERRSTR} = $Imager::ERRSTR;
3097 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3100 my $color = _color($opts{'color'});
3102 $self->{ERRSTR} = $Imager::ERRSTR;
3105 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3111 $self->{ERRSTR} = $self->_error_as_msg();
3118 my ($self, %opts) = @_;
3120 my $color = $opts{color};
3121 unless (defined $color) {
3122 $color = $self->{fg};
3123 defined $color or $color = NC(255, 255, 255);
3126 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3127 $color = _color($color)
3131 unless (exists $opts{'x'} && exists $opts{'y'}) {
3132 $self->{ERRSTR} = 'missing x and y parameters';
3138 if (ref $x && ref $y) {
3139 unless (@$x == @$y) {
3140 $self->{ERRSTR} = 'length of x and y mismatch';
3144 if ($color->isa('Imager::Color')) {
3145 for my $i (0..$#{$opts{'x'}}) {
3146 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3151 for my $i (0..$#{$opts{'x'}}) {
3152 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3160 if ($color->isa('Imager::Color')) {
3161 i_ppix($self->{IMG}, $x, $y, $color)
3165 i_ppixf($self->{IMG}, $x, $y, $color)
3176 my %opts = ( "type"=>'8bit', @_);
3178 unless (exists $opts{'x'} && exists $opts{'y'}) {
3179 $self->{ERRSTR} = 'missing x and y parameters';
3185 if (ref $x && ref $y) {
3186 unless (@$x == @$y) {
3187 $self->{ERRSTR} = 'length of x and y mismatch';
3191 if ($opts{"type"} eq '8bit') {
3192 for my $i (0..$#{$opts{'x'}}) {
3193 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3197 for my $i (0..$#{$opts{'x'}}) {
3198 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3201 return wantarray ? @result : \@result;
3204 if ($opts{"type"} eq '8bit') {
3205 return i_get_pixel($self->{IMG}, $x, $y);
3208 return i_gpixf($self->{IMG}, $x, $y);
3217 my %opts = ( type => '8bit', x=>0, @_);
3219 $self->_valid_image or return;
3221 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3223 unless (defined $opts{'y'}) {
3224 $self->_set_error("missing y parameter");
3228 if ($opts{type} eq '8bit') {
3229 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3232 elsif ($opts{type} eq 'float') {
3233 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3236 elsif ($opts{type} eq 'index') {
3237 unless (i_img_type($self->{IMG})) {
3238 $self->_set_error("type => index only valid on paletted images");
3241 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3245 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3252 my %opts = ( x=>0, @_);
3254 $self->_valid_image or return;
3256 unless (defined $opts{'y'}) {
3257 $self->_set_error("missing y parameter");
3262 if (ref $opts{pixels} && @{$opts{pixels}}) {
3263 # try to guess the type
3264 if ($opts{pixels}[0]->isa('Imager::Color')) {
3265 $opts{type} = '8bit';
3267 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3268 $opts{type} = 'float';
3271 $self->_set_error("missing type parameter and could not guess from pixels");
3277 $opts{type} = '8bit';
3281 if ($opts{type} eq '8bit') {
3282 if (ref $opts{pixels}) {
3283 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3286 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3289 elsif ($opts{type} eq 'float') {
3290 if (ref $opts{pixels}) {
3291 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3294 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3297 elsif ($opts{type} eq 'index') {
3298 if (ref $opts{pixels}) {
3299 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3302 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3306 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3313 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3315 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3317 unless (defined $opts{'y'}) {
3318 $self->_set_error("missing y parameter");
3322 if ($opts{target}) {
3323 my $target = $opts{target};
3324 my $offset = $opts{offset};
3325 if ($opts{type} eq '8bit') {
3326 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3327 $opts{y}, $opts{channels})
3329 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3330 return scalar(@samples);
3332 elsif ($opts{type} eq 'float') {
3333 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3334 $opts{y}, $opts{channels});
3335 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3336 return scalar(@samples);
3338 elsif ($opts{type} =~ /^(\d+)bit$/) {
3342 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3343 $opts{y}, $bits, $target,
3344 $offset, $opts{channels});
3345 unless (defined $count) {
3346 $self->_set_error(Imager->_error_as_msg);
3353 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3358 if ($opts{type} eq '8bit') {
3359 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3360 $opts{y}, $opts{channels});
3362 elsif ($opts{type} eq 'float') {
3363 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3364 $opts{y}, $opts{channels});
3366 elsif ($opts{type} =~ /^(\d+)bit$/) {
3370 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3371 $opts{y}, $bits, \@data, 0, $opts{channels})
3376 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3384 my %opts = ( x => 0, offset => 0, @_ );
3386 unless ($self->{IMG}) {
3387 $self->_set_error('setsamples: empty input image');
3391 unless(defined $opts{data} && ref $opts{data}) {
3392 $self->_set_error('setsamples: data parameter missing or invalid');
3396 unless ($opts{type} && $opts{type} =~ /^(\d+)bit$/) {
3397 $self->_set_error('setsamples: type parameter missing or invalid');
3402 unless (defined $opts{width}) {
3403 $opts{width} = $self->getwidth() - $opts{x};
3406 my $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3407 $opts{channels}, $opts{data}, $opts{offset},
3409 unless (defined $count) {
3410 $self->_set_error(Imager->_error_as_msg);
3417 # make an identity matrix of the given size
3421 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3422 for my $c (0 .. ($size-1)) {
3423 $matrix->[$c][$c] = 1;
3428 # general function to convert an image
3430 my ($self, %opts) = @_;
3433 unless (defined wantarray) {
3434 my @caller = caller;
3435 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3439 # the user can either specify a matrix or preset
3440 # the matrix overrides the preset
3441 if (!exists($opts{matrix})) {
3442 unless (exists($opts{preset})) {
3443 $self->{ERRSTR} = "convert() needs a matrix or preset";
3447 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3448 # convert to greyscale, keeping the alpha channel if any
3449 if ($self->getchannels == 3) {
3450 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3452 elsif ($self->getchannels == 4) {
3453 # preserve the alpha channel
3454 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3459 $matrix = _identity($self->getchannels);
3462 elsif ($opts{preset} eq 'noalpha') {
3463 # strip the alpha channel
3464 if ($self->getchannels == 2 or $self->getchannels == 4) {
3465 $matrix = _identity($self->getchannels);
3466 pop(@$matrix); # lose the alpha entry
3469 $matrix = _identity($self->getchannels);
3472 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3474 $matrix = [ [ 1 ] ];
3476 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3477 $matrix = [ [ 0, 1 ] ];
3479 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3480 $matrix = [ [ 0, 0, 1 ] ];
3482 elsif ($opts{preset} eq 'alpha') {
3483 if ($self->getchannels == 2 or $self->getchannels == 4) {
3484 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3487 # the alpha is just 1 <shrug>
3488 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3491 elsif ($opts{preset} eq 'rgb') {
3492 if ($self->getchannels == 1) {
3493 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3495 elsif ($self->getchannels == 2) {
3496 # preserve the alpha channel
3497 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3500 $matrix = _identity($self->getchannels);
3503 elsif ($opts{preset} eq 'addalpha') {
3504 if ($self->getchannels == 1) {
3505 $matrix = _identity(2);
3507 elsif ($self->getchannels == 3) {
3508 $matrix = _identity(4);
3511 $matrix = _identity($self->getchannels);
3515 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3521 $matrix = $opts{matrix};
3524 my $new = Imager->new;
3525 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3526 unless ($new->{IMG}) {
3527 # most likely a bad matrix
3528 $self->{ERRSTR} = _error_as_msg();
3534 # combine channels from multiple input images, a class method
3536 my ($class, %opts) = @_;
3538 my $src = delete $opts{src};
3540 $class->_set_error("src parameter missing");
3545 for my $img (@$src) {
3546 unless (eval { $img->isa("Imager") }) {
3547 $class->_set_error("src must contain image objects");
3550 unless ($img->{IMG}) {
3551 $class->_set_error("empty input image");
3554 push @imgs, $img->{IMG};
3557 if (my $channels = delete $opts{channels}) {
3558 $result = i_combine(\@imgs, $channels);
3561 $result = i_combine(\@imgs);
3564 $class->_set_error($class->_error_as_msg);
3568 my $img = $class->new;
3569 $img->{IMG} = $result;
3575 # general function to map an image through lookup tables
3578 my ($self, %opts) = @_;
3579 my @chlist = qw( red green blue alpha );
3581 if (!exists($opts{'maps'})) {
3582 # make maps from channel maps
3584 for $chnum (0..$#chlist) {
3585 if (exists $opts{$chlist[$chnum]}) {
3586 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3587 } elsif (exists $opts{'all'}) {
3588 $opts{'maps'}[$chnum] = $opts{'all'};
3592 if ($opts{'maps'} and $self->{IMG}) {
3593 i_map($self->{IMG}, $opts{'maps'} );
3599 my ($self, %opts) = @_;
3601 defined $opts{mindist} or $opts{mindist} = 0;
3603 defined $opts{other}
3604 or return $self->_set_error("No 'other' parameter supplied");
3605 defined $opts{other}{IMG}
3606 or return $self->_set_error("No image data in 'other' image");
3609 or return $self->_set_error("No image data");
3611 my $result = Imager->new;
3612 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3614 or return $self->_set_error($self->_error_as_msg());
3619 # destructive border - image is shrunk by one pixel all around
3622 my ($self,%opts)=@_;
3623 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3624 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3628 # Get the width of an image
3633 if (my $raw = $self->{IMG}) {
3634 return i_img_get_width($raw);
3637 $self->{ERRSTR} = 'image is empty'; return undef;
3641 # Get the height of an image
3646 if (my $raw = $self->{IMG}) {
3647 return i_img_get_height($raw);
3650 $self->{ERRSTR} = 'image is empty'; return undef;
3654 # Get number of channels in an image
3658 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3659 return i_img_getchannels($self->{IMG});
3666 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3667 return i_img_getmask($self->{IMG});
3675 if (!defined($self->{IMG})) {
3676 $self->{ERRSTR} = 'image is empty';
3679 unless (defined $opts{mask}) {
3680 $self->_set_error("mask parameter required");
3683 i_img_setmask( $self->{IMG} , $opts{mask} );
3688 # Get number of colors in an image
3692 my %opts=('maxcolors'=>2**30,@_);
3693 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
3694 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
3695 return ($rc==-1? undef : $rc);
3698 # Returns a reference to a hash. The keys are colour named (packed) and the
3699 # values are the number of pixels in this colour.
3700 sub getcolorusagehash {
3703 my %opts = ( maxcolors => 2**30, @_ );
3704 my $max_colors = $opts{maxcolors};
3705 unless (defined $max_colors && $max_colors > 0) {
3706 $self->_set_error('maxcolors must be a positive integer');
3710 unless (defined $self->{IMG}) {
3711 $self->_set_error('empty input image');
3715 my $channels= $self->getchannels;
3716 # We don't want to look at the alpha channel, because some gifs using it
3717 # doesn't define it for every colour (but only for some)
3718 $channels -= 1 if $channels == 2 or $channels == 4;
3720 my $height = $self->getheight;
3721 for my $y (0 .. $height - 1) {
3722 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
3723 while (length $colors) {
3724 $color_use{ substr($colors, 0, $channels, '') }++;
3726 keys %color_use > $max_colors
3732 # This will return a ordered array of the colour usage. Kind of the sorted
3733 # version of the values of the hash returned by getcolorusagehash.
3734 # You might want to add safety checks and change the names, etc...
3738 my %opts = ( maxcolors => 2**30, @_ );
3739 my $max_colors = $opts{maxcolors};
3740 unless (defined $max_colors && $max_colors > 0) {
3741 $self->_set_error('maxcolors must be a positive integer');
3745 unless (defined $self->{IMG}) {
3746 $self->_set_error('empty input image');
3750 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
3753 # draw string to an image
3757 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3759 my %input=('x'=>0, 'y'=>0, @_);
3760 defined($input{string}) or $input{string} = $input{text};
3762 unless(defined $input{string}) {
3763 $self->{ERRSTR}="missing required parameter 'string'";
3767 unless($input{font}) {
3768 $self->{ERRSTR}="missing required parameter 'font'";
3772 unless ($input{font}->draw(image=>$self, %input)) {
3784 unless ($self->{IMG}) {
3785 $self->{ERRSTR}='empty input image';
3794 my %input=('x'=>0, 'y'=>0, @_);
3795 defined $input{string}
3796 or $input{string} = $input{text};
3798 unless(exists $input{string}) {
3799 $self->_set_error("missing required parameter 'string'");
3803 unless($input{font}) {
3804 $self->_set_error("missing required parameter 'font'");
3809 unless (@result = $input{font}->align(image=>$img, %input)) {
3813 return wantarray ? @result : $result[0];
3816 my @file_limit_names = qw/width height bytes/;
3818 sub set_file_limits {
3825 @values{@file_limit_names} = (0) x @file_limit_names;
3828 @values{@file_limit_names} = i_get_image_file_limits();
3831 for my $key (keys %values) {
3832 defined $opts{$key} and $values{$key} = $opts{$key};
3835 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
3838 sub get_file_limits {
3839 i_get_image_file_limits();
3842 # Shortcuts that can be exported
3844 sub newcolor { Imager::Color->new(@_); }
3845 sub newfont { Imager::Font->new(@_); }
3847 require Imager::Color::Float;
3848 return Imager::Color::Float->new(@_);
3851 *NC=*newcolour=*newcolor;
3858 #### Utility routines
3861 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
3865 my ($self, $msg) = @_;
3868 $self->{ERRSTR} = $msg;
3876 # Default guess for the type of an image from extension
3878 my @simple_types = qw(png tga gif raw ico cur xpm mng jng ilbm pcx psd eps);
3882 ( map { $_ => $_ } @simple_types ),
3888 pnm => "pnm", # technically wrong, but historically it works in Imager
3901 sub def_guess_type {
3904 my ($ext) = $name =~ /\.([^.]+)$/
3907 my $type = $ext_types{$ext}
3914 return @combine_types;
3917 # get the minimum of a list
3921 for(@_) { if ($_<$mx) { $mx=$_; }}
3925 # get the maximum of a list
3929 for(@_) { if ($_>$mx) { $mx=$_; }}
3933 # string stuff for iptc headers
3937 $str = substr($str,3);
3938 $str =~ s/[\n\r]//g;
3945 # A little hack to parse iptc headers.
3950 my($caption,$photogr,$headln,$credit);
3952 my $str=$self->{IPTCRAW};
3957 @ar=split(/8BIM/,$str);
3962 @sar=split(/\034\002/);
3963 foreach $item (@sar) {
3964 if ($item =~ m/^x/) {
3965 $caption = _clean($item);
3968 if ($item =~ m/^P/) {
3969 $photogr = _clean($item);
3972 if ($item =~ m/^i/) {
3973 $headln = _clean($item);
3976 if ($item =~ m/^n/) {
3977 $credit = _clean($item);
3983 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
3990 or die "Only C language supported";
3992 require Imager::ExtUtils;
3993 return Imager::ExtUtils->inline_config;
3996 # threads shouldn't try to close raw Imager objects
3997 sub Imager::ImgRaw::CLONE_SKIP { 1 }
4000 # this serves two purposes:
4001 # - a class method to load the file support modules included with Imager
4002 # (or were included, once the library dependent modules are split out)
4003 # - something for Module::ScanDeps to analyze
4004 # https://rt.cpan.org/Ticket/Display.html?id=6566
4006 eval { require Imager::File::GIF };
4007 eval { require Imager::File::JPEG };
4008 eval { require Imager::File::PNG };
4009 eval { require Imager::File::SGI };
4010 eval { require Imager::File::TIFF };
4011 eval { require Imager::File::ICO };
4012 eval { require Imager::Font::W32 };
4013 eval { require Imager::Font::FT2 };
4014 eval { require Imager::Font::T1 };
4017 # backward compatibility for %formats
4018 package Imager::FORMATS;
4020 use constant IX_FORMATS => 0;
4021 use constant IX_LIST => 1;
4022 use constant IX_INDEX => 2;
4023 use constant IX_CLASSES => 3;
4026 my ($class, $formats, $classes) = @_;
4028 return bless [ $formats, [ ], 0, $classes ], $class;
4032 my ($self, $key) = @_;
4034 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
4037 my $loaded = Imager::_load_file($file, \$error);
4042 if ($error =~ /^Can't locate /) {
4043 $error = "Can't locate $file";
4045 $reader_load_errors{$key} = $writer_load_errors{$key} = $error;
4048 $self->[IX_FORMATS]{$key} = $value;
4054 my ($self, $key) = @_;
4056 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
4058 $self->[IX_CLASSES]{$key} or return undef;
4060 return $self->_check($key);
4064 die "%Imager::formats is not user monifiable";
4068 die "%Imager::formats is not user monifiable";
4072 die "%Imager::formats is not user monifiable";
4076 my ($self, $key) = @_;
4078 if (exists $self->[IX_FORMATS]{$key}) {
4079 my $value = $self->[IX_FORMATS]{$key}
4084 $self->_check($key) or return 1==0;
4092 unless (@{$self->[IX_LIST]}) {
4094 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4095 keys %{$self->[IX_FORMATS]};
4097 for my $key (keys %{$self->[IX_CLASSES]}) {
4098 $self->[IX_FORMATS]{$key} and next;
4100 and push @{$self->[IX_LIST]}, $key;
4104 @{$self->[IX_LIST]} or return;
4105 $self->[IX_INDEX] = 1;
4106 return $self->[IX_LIST][0];
4112 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4115 return $self->[IX_LIST][$self->[IX_INDEX]++];
4121 return scalar @{$self->[IX_LIST]};
4126 # Below is the stub of documentation for your module. You better edit it!
4130 Imager - Perl extension for Generating 24 bit Images
4140 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4145 # see Imager::Files for information on the read() method
4146 my $img = Imager->new(file=>$file)
4147 or die Imager->errstr();
4149 $file =~ s/\.[^.]*$//;
4151 # Create smaller version
4152 # documented in Imager::Transformations
4153 my $thumb = $img->scale(scalefactor=>.3);
4155 # Autostretch individual channels
4156 $thumb->filter(type=>'autolevels');
4158 # try to save in one of these formats
4161 for $format ( qw( png gif jpeg tiff ppm ) ) {
4162 # Check if given format is supported
4163 if ($Imager::formats{$format}) {
4164 $file.="_low.$format";
4165 print "Storing image as: $file\n";
4166 # documented in Imager::Files
4167 $thumb->write(file=>$file) or
4175 Imager is a module for creating and altering images. It can read and
4176 write various image formats, draw primitive shapes like lines,and
4177 polygons, blend multiple images together in various ways, scale, crop,
4178 render text and more.
4180 =head2 Overview of documentation
4186 Imager - This document - Synopsis, Example, Table of Contents and
4191 L<Imager::Tutorial> - a brief introduction to Imager.
4195 L<Imager::Cookbook> - how to do various things with Imager.
4199 L<Imager::ImageTypes> - Basics of constructing image objects with
4200 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4201 8/16/double bits/channel, color maps, channel masks, image tags, color
4202 quantization. Also discusses basic image information methods.
4206 L<Imager::Files> - IO interaction, reading/writing images, format
4211 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4216 L<Imager::Color> - Color specification.
4220 L<Imager::Fill> - Fill pattern specification.
4224 L<Imager::Font> - General font rendering, bounding boxes and font
4229 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4230 blending, pasting, convert and map.
4234 L<Imager::Engines> - Programmable transformations through
4235 C<transform()>, C<transform2()> and C<matrix_transform()>.
4239 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4244 L<Imager::Expr> - Expressions for evaluation engine used by
4249 L<Imager::Matrix2d> - Helper class for affine transformations.
4253 L<Imager::Fountain> - Helper for making gradient profiles.
4257 L<Imager::API> - using Imager's C API
4261 L<Imager::APIRef> - API function reference
4265 L<Imager::Inline> - using Imager's C API from Inline::C
4269 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4273 =head2 Basic Overview
4275 An Image object is created with C<$img = Imager-E<gt>new()>.
4278 $img=Imager->new(); # create empty image
4279 $img->read(file=>'lena.png',type=>'png') or # read image from file
4280 die $img->errstr(); # give an explanation
4281 # if something failed
4283 or if you want to create an empty image:
4285 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4287 This example creates a completely black image of width 400 and height
4290 =head1 ERROR HANDLING
4292 In general a method will return false when it fails, if it does use
4293 the C<errstr()> method to find out why:
4299 Returns the last error message in that context.
4301 If the last error you received was from calling an object method, such
4302 as read, call errstr() as an object method to find out why:
4304 my $image = Imager->new;
4305 $image->read(file => 'somefile.gif')
4306 or die $image->errstr;
4308 If it was a class method then call errstr() as a class method:
4310 my @imgs = Imager->read_multi(file => 'somefile.gif')
4311 or die Imager->errstr;
4313 Note that in some cases object methods are implemented in terms of
4314 class methods so a failing object method may set both.
4318 The C<Imager-E<gt>new> method is described in detail in
4319 L<Imager::ImageTypes>.
4323 Where to find information on methods for Imager class objects.
4325 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4328 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4330 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4333 arc() - L<Imager::Draw/arc()> - draw a filled arc
4335 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4338 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4340 circle() - L<Imager::Draw/circle()> - draw a filled circle
4342 close_log() - L<Imager::ImageTypes/close_log()> - close the Imager
4345 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4346 colors in an image's palette (paletted images only)
4348 combine() - L<Imager::Transformations/combine()> - combine channels
4349 from one or more images.
4351 combines() - L<Imager::Draw/combines()> - return a list of the
4352 different combine type keywords
4354 compose() - L<Imager::Transformations/compose()> - compose one image
4357 convert() - L<Imager::Transformations/convert()> - transform the color
4360 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4363 crop() - L<Imager::Transformations/crop()> - extract part of an image
4365 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4366 used to guess the output file format based on the output file name
4368 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4370 difference() - L<Imager::Filters/difference()> - produce a difference
4371 images from two input images.
4373 errstr() - L</errstr()> - the error from the last failed operation.
4375 filter() - L<Imager::Filters/filter()> - image filtering
4377 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4378 palette, if it has one
4380 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4383 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4386 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4387 samples per pixel for an image
4389 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4390 different colors used by an image (works for direct color images)
4392 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4393 palette, if it has one
4395 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4397 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4399 get_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4401 getheight() - L<Imager::ImageTypes/getheight()> - height of the image in
4404 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4406 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4409 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4410 row or partial row of pixels.
4412 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4413 row or partial row of pixels.
4415 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4418 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4421 init() - L<Imager::ImageTypes/init()>
4423 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4424 image write functions should write the image in their bilevel (blank
4425 and white, no gray levels) format
4427 is_logging() L<Imager::ImageTypes/is_logging()> - test if the debug
4430 line() - L<Imager::Draw/line()> - draw an interval
4432 load_plugin() - L<Imager::Filters/load_plugin()>
4434 log() - L<Imager::ImageTypes/log()> - send a message to the debugging
4437 make_palette() - L<Imager::ImageTypes/make_palette()> - produce a
4438 color palette from one or more input images.
4440 map() - L<Imager::Transformations/"Color Mappings"> - remap color
4443 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4445 matrix_transform() - L<Imager::Engines/matrix_transform()>
4447 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4449 NC() - L<Imager::Handy/NC()>
4451 NCF() - L<Imager::Handy/NCF()>
4453 new() - L<Imager::ImageTypes/new()>
4455 newcolor() - L<Imager::Handy/newcolor()>
4457 newcolour() - L<Imager::Handy/newcolour()>
4459 newfont() - L<Imager::Handy/newfont()>
4461 NF() - L<Imager::Handy/NF()>
4463 open() - L<Imager::Files> - an alias for read()
4465 open_log() - L<Imager::ImageTypes/open_log()> - open the debug log.
4469 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4472 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4475 polygon() - L<Imager::Draw/polygon()>
4477 polyline() - L<Imager::Draw/polyline()>
4479 preload() - L<Imager::Files/preload()>
4481 read() - L<Imager::Files/read()> - read a single image from an image file
4483 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
4486 read_types() - L<Imager::Files/read_types()> - list image types Imager
4489 register_filter() - L<Imager::Filters/register_filter()>
4491 register_reader() - L<Imager::Files/register_reader()>
4493 register_writer() - L<Imager::Files/register_writer()>
4495 rotate() - L<Imager::Transformations/rotate()>
4497 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
4498 onto an image and use the alpha channel
4500 scale() - L<Imager::Transformations/scale()>
4502 scale_calculate() - L<Imager::Transformations/scale_calculate()>
4504 scaleX() - L<Imager::Transformations/scaleX()>
4506 scaleY() - L<Imager::Transformations/scaleY()>
4508 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
4511 set_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4513 setmask() - L<Imager::ImageTypes/setmask()>
4515 setpixel() - L<Imager::Draw/setpixel()>
4517 setsamples() - L<Imager::Draw/setsamples()>
4519 setscanline() - L<Imager::Draw/setscanline()>
4521 settag() - L<Imager::ImageTypes/settag()>
4523 string() - L<Imager::Draw/string()> - draw text on an image
4525 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
4527 to_paletted() - L<Imager::ImageTypes/to_paletted()>
4529 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
4531 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
4533 to_rgb_double() - L<Imager::ImageTypes/to_rgb_double()> - convert to
4534 double per sample image.
4536 transform() - L<Imager::Engines/"transform()">
4538 transform2() - L<Imager::Engines/"transform2()">
4540 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
4542 unload_plugin() - L<Imager::Filters/unload_plugin()>
4544 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
4547 write() - L<Imager::Files/write()> - write an image to a file
4549 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
4552 write_types() - L<Imager::Files/read_types()> - list image types Imager
4555 =head1 CONCEPT INDEX
4557 animated GIF - L<Imager::Files/"Writing an animated GIF">
4559 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
4560 L<Imager::ImageTypes/"Common Tags">.
4562 blend - alpha blending one image onto another
4563 L<Imager::Transformations/rubthrough()>
4565 blur - L<Imager::Filters/gaussian>, L<Imager::Filters/conv>
4567 boxes, drawing - L<Imager::Draw/box()>
4569 changes between image - L<Imager::Filters/"Image Difference">
4571 channels, combine into one image - L<Imager::Transformations/combine()>
4573 color - L<Imager::Color>
4575 color names - L<Imager::Color>, L<Imager::Color::Table>
4577 combine modes - L<Imager::Draw/"Combine Types">
4579 compare images - L<Imager::Filters/"Image Difference">
4581 contrast - L<Imager::Filters/contrast>, L<Imager::Filters/autolevels>
4583 convolution - L<Imager::Filters/conv>
4585 cropping - L<Imager::Transformations/crop()>
4587 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4589 C<diff> images - L<Imager::Filters/"Image Difference">
4591 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
4592 L<Imager::Cookbook/"Image spatial resolution">
4594 drawing boxes - L<Imager::Draw/box()>
4596 drawing lines - L<Imager::Draw/line()>
4598 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
4600 error message - L</"ERROR HANDLING">
4602 files, font - L<Imager::Font>
4604 files, image - L<Imager::Files>
4606 filling, types of fill - L<Imager::Fill>
4608 filling, boxes - L<Imager::Draw/box()>
4610 filling, flood fill - L<Imager::Draw/flood_fill()>
4612 flood fill - L<Imager::Draw/flood_fill()>
4614 fonts - L<Imager::Font>
4616 fonts, drawing with - L<Imager::Draw/string()>,
4617 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
4619 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4621 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
4623 fountain fill - L<Imager::Fill/"Fountain fills">,
4624 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4625 L<Imager::Filters/gradgen>
4627 GIF files - L<Imager::Files/"GIF">
4629 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
4631 gradient fill - L<Imager::Fill/"Fountain fills">,
4632 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4633 L<Imager::Filters/gradgen>
4635 gray scale, convert image to - L<Imager::Transformations/convert()>
4637 gaussian blur - L<Imager::Filters/gaussian>
4639 hatch fills - L<Imager::Fill/"Hatched fills">
4641 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4643 invert image - L<Imager::Filters/hardinvert>,
4644 L<Imager::Filters/hardinvertall>
4646 JPEG - L<Imager::Files/"JPEG">
4648 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
4650 lines, drawing - L<Imager::Draw/line()>
4652 matrix - L<Imager::Matrix2d>,
4653 L<Imager::Engines/"Matrix Transformations">,
4654 L<Imager::Font/transform()>
4656 metadata, image - L<Imager::ImageTypes/"Tags">
4658 mosaic - L<Imager::Filters/mosaic>
4660 noise, filter - L<Imager::Filters/noise>
4662 noise, rendered - L<Imager::Filters/turbnoise>,
4663 L<Imager::Filters/radnoise>
4665 paste - L<Imager::Transformations/paste()>,
4666 L<Imager::Transformations/rubthrough()>
4668 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
4669 L<Imager::ImageTypes/new()>
4671 =for stopwords posterize
4673 posterize - L<Imager::Filters/postlevels>
4675 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
4677 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
4679 rectangles, drawing - L<Imager::Draw/box()>
4681 resizing an image - L<Imager::Transformations/scale()>,
4682 L<Imager::Transformations/crop()>
4684 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
4686 saving an image - L<Imager::Files>
4688 scaling - L<Imager::Transformations/scale()>
4690 SGI files - L<Imager::Files/"SGI (RGB, BW)">
4692 sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
4694 size, image - L<Imager::ImageTypes/getwidth()>,
4695 L<Imager::ImageTypes/getheight()>
4697 size, text - L<Imager::Font/bounding_box()>
4699 tags, image metadata - L<Imager::ImageTypes/"Tags">
4701 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
4702 L<Imager::Font::Wrap>
4704 text, wrapping text in an area - L<Imager::Font::Wrap>
4706 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4708 tiles, color - L<Imager::Filters/mosaic>
4710 transparent images - L<Imager::ImageTypes>,
4711 L<Imager::Cookbook/"Transparent PNG">
4713 =for stopwords unsharp
4715 unsharp mask - L<Imager::Filters/unsharpmask>
4717 watermark - L<Imager::Filters/watermark>
4719 writing an image to a file - L<Imager::Files>
4723 Imager doesn't support perl threads.
4725 Imager has limited code to prevent double frees if you create images,
4726 colors etc, and then create a thread, but has no code to prevent two
4727 threads entering Imager's error handling code, and none is likely to
4732 The best place to get help with Imager is the mailing list.
4734 To subscribe send a message with C<subscribe> in the body to:
4736 imager-devel+request@molar.is
4742 L<http://www.molar.is/en/lists/imager-devel/>
4746 where you can also find the mailing list archive.
4748 You can report bugs by pointing your browser at:
4752 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
4756 or by sending an email to:
4760 bug-Imager@rt.cpan.org
4764 Please remember to include the versions of Imager, perl, supporting
4765 libraries, and any relevant code. If you have specific images that
4766 cause the problems, please include those too.
4768 If you don't want to publish your email address on a mailing list you
4769 can use CPAN::Forum:
4771 http://www.cpanforum.com/dist/Imager
4773 You will need to register to post.
4775 =head1 CONTRIBUTING TO IMAGER
4781 If you like or dislike Imager, you can add a public review of Imager
4784 http://cpanratings.perl.org/dist/Imager
4786 =for stopwords Bitcard
4788 This requires a Bitcard account (http://www.bitcard.org).
4790 You can also send email to the maintainer below.
4792 If you send me a bug report via email, it will be copied to Request
4797 I accept patches, preferably against the master branch in git. Please
4798 include an explanation of the reason for why the patch is needed or
4801 Your patch should include regression tests where possible, otherwise
4802 it will be delayed until I get a chance to write them.
4804 To browse Imager's git repository:
4806 http://git.imager.perl.org/imager.git
4810 https://github.com/tonycoz/imager
4814 git clone git://git.imager.perl.org/imager.git
4818 git clone git://github.com/tonycoz/imager.git
4822 Tony Cook <tonyc@cpan.org> is the current maintainer for Imager.
4824 Arnar M. Hrafnkelsson is the original author of Imager.
4826 Many others have contributed to Imager, please see the C<README> for a
4831 Imager is licensed under the same terms as perl itself.
4834 makeblendedfont Fontforge
4836 A test font, generated by the Debian packaged Fontforge,
4837 F<FT2/fontfiles/MMOne.pfb>, contains a Postscript operator definition
4838 copyrighted by Adobe. See F<adobe.txt> in the source for license
4843 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
4844 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
4845 L<Imager::Font>(3), L<Imager::Transformations>(3),
4846 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
4847 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
4849 L<http://imager.perl.org/>
4851 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
4853 Other perl imaging modules include:
4855 L<GD>(3), L<Image::Magick>(3), L<Graphics::Magick>(3),
4856 L<Prima::Image>, L<IPA>.
4858 If you're trying to use Imager for array processing, you should
4859 probably using L<PDL>.