4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR %OPCODES $I2P $FORMATGUESS $warn_obsolete);
121 # registered file readers
124 # registered file writers
127 # modules we attempted to autoload
128 my %attempted_to_load;
130 # library keys that are image file formats
131 my %file_formats = map { $_ => 1 } qw/tiff pnm gif png jpeg raw bmp tga/;
133 # image pixel combine types
135 qw/none normal multiply dissolve add subtract diff lighten darken
136 hue saturation value color/;
138 @combine_types{@combine_types} = 0 .. $#combine_types;
139 $combine_types{mult} = $combine_types{multiply};
140 $combine_types{'sub'} = $combine_types{subtract};
141 $combine_types{sat} = $combine_types{saturation};
143 # this will be used to store global defaults at some point
152 XSLoader::load(Imager => $VERSION);
156 push @ISA, 'DynaLoader';
157 bootstrap Imager $VERSION;
164 png => "Imager::File::PNG",
165 gif => "Imager::File::GIF",
166 tiff => "Imager::File::TIFF",
167 jpeg => "Imager::File::JPEG",
168 w32 => "Imager::Font::W32",
169 ft2 => "Imager::Font::FT2",
170 t1 => "Imager::Font::T1",
173 tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
176 for(i_list_formats()) { $formats_low{$_}++; }
178 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
182 # the members of the subhashes under %filters are:
183 # callseq - a list of the parameters to the underlying filter in the
184 # order they are passed
185 # callsub - a code ref that takes a named parameter list and calls the
187 # defaults - a hash of default values
188 # names - defines names for value of given parameters so if the names
189 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
190 # foo parameter, the filter will receive 1 for the foo
193 callseq => ['image','intensity'],
194 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
198 callseq => ['image', 'amount', 'subtype'],
199 defaults => { amount=>3,subtype=>0 },
200 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
203 $filters{hardinvert} ={
204 callseq => ['image'],
206 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
209 $filters{hardinvertall} =
211 callseq => ['image'],
213 callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
216 $filters{autolevels} ={
217 callseq => ['image','lsat','usat','skew'],
218 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
219 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
222 $filters{turbnoise} ={
223 callseq => ['image'],
224 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
225 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
228 $filters{radnoise} ={
229 callseq => ['image'],
230 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
231 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
236 callseq => ['image', 'coef'],
241 i_conv($hsh{image},$hsh{coef})
242 or die Imager->_error_as_msg() . "\n";
248 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
249 defaults => { dist => 0 },
253 my @colors = @{$hsh{colors}};
256 i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
260 $filters{nearest_color} =
262 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
267 # make sure the segments are specified with colors
269 for my $color (@{$hsh{colors}}) {
270 my $new_color = _color($color)
271 or die $Imager::ERRSTR."\n";
272 push @colors, $new_color;
275 i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors,
277 or die Imager->_error_as_msg() . "\n";
280 $filters{gaussian} = {
281 callseq => [ 'image', 'stddev' ],
283 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
287 callseq => [ qw(image size) ],
288 defaults => { size => 20 },
289 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
293 callseq => [ qw(image bump elevation lightx lighty st) ],
294 defaults => { elevation=>0, st=> 2 },
297 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
298 $hsh{lightx}, $hsh{lighty}, $hsh{st});
301 $filters{bumpmap_complex} =
303 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
320 for my $cname (qw/Ia Il Is/) {
321 my $old = $hsh{$cname};
322 my $new_color = _color($old)
323 or die $Imager::ERRSTR, "\n";
324 $hsh{$cname} = $new_color;
326 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
327 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
328 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
332 $filters{postlevels} =
334 callseq => [ qw(image levels) ],
335 defaults => { levels => 10 },
336 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
338 $filters{watermark} =
340 callseq => [ qw(image wmark tx ty pixdiff) ],
341 defaults => { pixdiff=>10, tx=>0, ty=>0 },
345 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
351 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
353 ftype => { linear => 0,
359 repeat => { none => 0,
374 multiply => 2, mult => 2,
377 subtract => 5, 'sub' => 5,
387 defaults => { ftype => 0, repeat => 0, combine => 0,
388 super_sample => 0, ssample_param => 4,
401 # make sure the segments are specified with colors
403 for my $segment (@{$hsh{segments}}) {
404 my @new_segment = @$segment;
406 $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
407 push @segments, \@new_segment;
410 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
411 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
412 $hsh{ssample_param}, \@segments)
413 or die Imager->_error_as_msg() . "\n";
416 $filters{unsharpmask} =
418 callseq => [ qw(image stddev scale) ],
419 defaults => { stddev=>2.0, scale=>1.0 },
423 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
427 $FORMATGUESS=\&def_guess_type;
437 # NOTE: this might be moved to an import override later on
442 if ($_[$i] eq '-log-stderr') {
450 goto &Exporter::import;
454 i_init_log($_[0],$_[1]);
455 i_log_entry("Imager $VERSION starting\n", 1);
460 my %parms=(loglevel=>1,@_);
462 init_log($parms{'log'},$parms{'loglevel'});
465 if (exists $parms{'warn_obsolete'}) {
466 $warn_obsolete = $parms{'warn_obsolete'};
469 if (exists $parms{'t1log'}) {
471 Imager::Font::T1::i_init_t1($parms{'t1log'});
478 print "shutdown code\n";
479 # for(keys %instances) { $instances{$_}->DESTROY(); }
480 malloc_state(); # how do decide if this should be used? -- store something from the import
481 print "Imager exiting\n";
485 # Load a filter plugin
490 my ($DSO_handle,$str)=DSO_open($filename);
491 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
492 my %funcs=DSO_funclist($DSO_handle);
493 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
495 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
497 $DSOs{$filename}=[$DSO_handle,\%funcs];
500 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
501 $DEBUG && print "eval string:\n",$evstr,"\n";
513 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
514 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
515 for(keys %{$funcref}) {
517 $DEBUG && print "unloading: $_\n";
519 my $rc=DSO_close($DSO_handle);
520 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
524 # take the results of i_error() and make a message out of it
526 return join(": ", map $_->[0], i_errors());
529 # this function tries to DWIM for color parameters
530 # color objects are used as is
531 # simple scalars are simply treated as single parameters to Imager::Color->new
532 # hashrefs are treated as named argument lists to Imager::Color->new
533 # arrayrefs are treated as list arguments to Imager::Color->new iff any
535 # other arrayrefs are treated as list arguments to Imager::Color::Float
539 # perl 5.6.0 seems to do weird things to $arg if we don't make an
540 # explicitly stringified copy
541 # I vaguely remember a bug on this on p5p, but couldn't find it
542 # through bugs.perl.org (I had trouble getting it to find any bugs)
543 my $copy = $arg . "";
547 if (UNIVERSAL::isa($arg, "Imager::Color")
548 || UNIVERSAL::isa($arg, "Imager::Color::Float")) {
552 if ($copy =~ /^HASH\(/) {
553 $result = Imager::Color->new(%$arg);
555 elsif ($copy =~ /^ARRAY\(/) {
556 $result = Imager::Color->new(@$arg);
559 $Imager::ERRSTR = "Not a color";
564 # assume Imager::Color::new knows how to handle it
565 $result = Imager::Color->new($arg);
572 my ($self, $combine, $default) = @_;
574 if (!defined $combine && ref $self) {
575 $combine = $self->{combine};
577 defined $combine or $combine = $defaults{combine};
578 defined $combine or $combine = $default;
580 if (exists $combine_types{$combine}) {
581 $combine = $combine_types{$combine};
590 $self->{IMG} and return 1;
592 $self->_set_error('empty input image');
597 # returns first defined parameter
600 return $_ if defined $_;
606 # Methods to be called on objects.
609 # Create a new Imager object takes very few parameters.
610 # usually you call this method and then call open from
611 # the resulting object
618 $self->{IMG}=undef; # Just to indicate what exists
619 $self->{ERRSTR}=undef; #
620 $self->{DEBUG}=$DEBUG;
621 $self->{DEBUG} and print "Initialized Imager\n";
622 if (defined $hsh{xsize} || defined $hsh{ysize}) {
623 unless ($self->img_set(%hsh)) {
624 $Imager::ERRSTR = $self->{ERRSTR};
628 elsif (defined $hsh{file} ||
631 defined $hsh{callback} ||
632 defined $hsh{readcb} ||
633 defined $hsh{data}) {
634 # allow $img = Imager->new(file => $filename)
637 # type is already used as a parameter to new(), rename it for the
639 if ($hsh{filetype}) {
640 $extras{type} = $hsh{filetype};
642 unless ($self->read(%hsh, %extras)) {
643 $Imager::ERRSTR = $self->{ERRSTR};
651 # Copy an entire image with no changes
652 # - if an image has magic the copy of it will not be magical
656 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
658 unless (defined wantarray) {
660 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
664 my $newcopy=Imager->new();
665 $newcopy->{IMG} = i_copy($self->{IMG});
674 unless ($self->{IMG}) {
675 $self->_set_error('empty input image');
678 my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
679 my $src = $input{img} || $input{src};
681 $self->_set_error("no source image");
684 $input{left}=0 if $input{left} <= 0;
685 $input{top}=0 if $input{top} <= 0;
687 my($r,$b)=i_img_info($src->{IMG});
688 my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
689 my ($src_right, $src_bottom);
690 if ($input{src_coords}) {
691 ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
694 if (defined $input{src_maxx}) {
695 $src_right = $input{src_maxx};
697 elsif (defined $input{width}) {
698 if ($input{width} <= 0) {
699 $self->_set_error("paste: width must me positive");
702 $src_right = $src_left + $input{width};
707 if (defined $input{src_maxy}) {
708 $src_bottom = $input{src_maxy};
710 elsif (defined $input{height}) {
711 if ($input{height} < 0) {
712 $self->_set_error("paste: height must be positive");
715 $src_bottom = $src_top + $input{height};
722 $src_right > $r and $src_right = $r;
723 $src_bottom > $b and $src_bottom = $b;
725 if ($src_right <= $src_left
726 || $src_bottom < $src_top) {
727 $self->_set_error("nothing to paste");
731 i_copyto($self->{IMG}, $src->{IMG},
732 $src_left, $src_top, $src_right, $src_bottom,
733 $input{left}, $input{top});
735 return $self; # What should go here??
738 # Crop an image - i.e. return a new image that is smaller
742 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
744 unless (defined wantarray) {
746 warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
752 my ($w, $h, $l, $r, $b, $t) =
753 @hsh{qw(width height left right bottom top)};
755 # work through the various possibilities
760 elsif (!defined $r) {
761 $r = $self->getwidth;
773 $l = int(0.5+($self->getwidth()-$w)/2);
778 $r = $self->getwidth;
784 elsif (!defined $b) {
785 $b = $self->getheight;
797 $t=int(0.5+($self->getheight()-$h)/2);
802 $b = $self->getheight;
805 ($l,$r)=($r,$l) if $l>$r;
806 ($t,$b)=($b,$t) if $t>$b;
809 $r > $self->getwidth and $r = $self->getwidth;
811 $b > $self->getheight and $b = $self->getheight;
813 if ($l == $r || $t == $b) {
814 $self->_set_error("resulting image would have no content");
817 if( $r < $l or $b < $t ) {
818 $self->_set_error("attempting to crop outside of the image");
821 my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
823 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
828 my ($self, %opts) = @_;
830 $self->{IMG} or return $self->_set_error("Not a valid image");
832 my $x = $opts{xsize} || $self->getwidth;
833 my $y = $opts{ysize} || $self->getheight;
834 my $channels = $opts{channels} || $self->getchannels;
836 my $out = Imager->new;
837 if ($channels == $self->getchannels) {
838 $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
841 $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
843 unless ($out->{IMG}) {
844 $self->{ERRSTR} = $self->_error_as_msg;
851 # Sets an image to a certain size and channel number
852 # if there was previously data in the image it is discarded
857 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
859 if (defined($self->{IMG})) {
860 # let IIM_DESTROY destroy it, it's possible this image is
861 # referenced from a virtual image (like masked)
862 #i_img_destroy($self->{IMG});
866 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
867 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
868 $hsh{maxcolors} || 256);
870 elsif ($hsh{bits} eq 'double') {
871 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
873 elsif ($hsh{bits} == 16) {
874 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
877 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
881 unless ($self->{IMG}) {
882 $self->{ERRSTR} = Imager->_error_as_msg();
889 # created a masked version of the current image
893 $self or return undef;
894 my %opts = (left => 0,
896 right => $self->getwidth,
897 bottom => $self->getheight,
899 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
901 my $result = Imager->new;
902 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
903 $opts{top}, $opts{right} - $opts{left},
904 $opts{bottom} - $opts{top});
905 unless ($result->{IMG}) {
906 $self->_set_error(Imager->_error_as_msg);
910 # keep references to the mask and base images so they don't
912 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
917 # convert an RGB image into a paletted image
921 if (@_ != 1 && !ref $_[0]) {
928 unless (defined wantarray) {
930 warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
934 my $result = Imager->new;
935 $result->{IMG} = i_img_to_pal($self->{IMG}, $opts);
937 #print "Type ", i_img_type($result->{IMG}), "\n";
939 if ($result->{IMG}) {
943 $self->{ERRSTR} = $self->_error_as_msg;
948 # convert a paletted (or any image) to an 8-bit/channel RGB images
953 unless (defined wantarray) {
955 warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
960 $result = Imager->new;
961 $result->{IMG} = i_img_to_rgb($self->{IMG})
968 # convert a paletted (or any image) to an 8-bit/channel RGB images
973 unless (defined wantarray) {
975 warn "to_rgb16() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
980 $result = Imager->new;
981 $result->{IMG} = i_img_to_rgb16($self->{IMG})
990 my %opts = (colors=>[], @_);
992 unless ($self->{IMG}) {
993 $self->_set_error("empty input image");
997 my @colors = @{$opts{colors}}
1000 for my $color (@colors) {
1001 $color = _color($color);
1003 $self->_set_error($Imager::ERRSTR);
1008 return i_addcolors($self->{IMG}, @colors);
1013 my %opts = (start=>0, colors=>[], @_);
1015 unless ($self->{IMG}) {
1016 $self->_set_error("empty input image");
1020 my @colors = @{$opts{colors}}
1023 for my $color (@colors) {
1024 $color = _color($color);
1026 $self->_set_error($Imager::ERRSTR);
1031 return i_setcolors($self->{IMG}, $opts{start}, @colors);
1037 if (!exists $opts{start} && !exists $opts{count}) {
1040 $opts{count} = $self->colorcount;
1042 elsif (!exists $opts{count}) {
1045 elsif (!exists $opts{start}) {
1050 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
1054 i_colorcount($_[0]{IMG});
1058 i_maxcolors($_[0]{IMG});
1064 $opts{color} or return undef;
1066 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
1071 my $bits = $self->{IMG} && i_img_bits($self->{IMG});
1072 if ($bits && $bits == length(pack("d", 1)) * 8) {
1081 return i_img_type($self->{IMG}) ? "paletted" : "direct";
1087 $self->{IMG} and i_img_virtual($self->{IMG});
1093 $self->{IMG} or return;
1095 return i_img_is_monochrome($self->{IMG});
1099 my ($self, %opts) = @_;
1101 $self->{IMG} or return;
1103 if (defined $opts{name}) {
1107 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
1108 push @result, (i_tags_get($self->{IMG}, $found))[1];
1111 return wantarray ? @result : $result[0];
1113 elsif (defined $opts{code}) {
1117 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
1118 push @result, (i_tags_get($self->{IMG}, $found))[1];
1125 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
1128 return i_tags_count($self->{IMG});
1137 return -1 unless $self->{IMG};
1139 if (defined $opts{value}) {
1140 if ($opts{value} =~ /^\d+$/) {
1142 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
1145 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
1148 elsif (defined $opts{data}) {
1149 # force addition as a string
1150 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
1153 $self->{ERRSTR} = "No value supplied";
1157 elsif ($opts{code}) {
1158 if (defined $opts{value}) {
1159 if ($opts{value} =~ /^\d+$/) {
1161 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
1164 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
1167 elsif (defined $opts{data}) {
1168 # force addition as a string
1169 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
1172 $self->{ERRSTR} = "No value supplied";
1185 return 0 unless $self->{IMG};
1187 if (defined $opts{'index'}) {
1188 return i_tags_delete($self->{IMG}, $opts{'index'});
1190 elsif (defined $opts{name}) {
1191 return i_tags_delbyname($self->{IMG}, $opts{name});
1193 elsif (defined $opts{code}) {
1194 return i_tags_delbycode($self->{IMG}, $opts{code});
1197 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
1203 my ($self, %opts) = @_;
1206 $self->deltag(name=>$opts{name});
1207 return $self->addtag(name=>$opts{name}, value=>$opts{value});
1209 elsif (defined $opts{code}) {
1210 $self->deltag(code=>$opts{code});
1211 return $self->addtag(code=>$opts{code}, value=>$opts{value});
1219 sub _get_reader_io {
1220 my ($self, $input) = @_;
1223 return $input->{io}, undef;
1225 elsif ($input->{fd}) {
1226 return io_new_fd($input->{fd});
1228 elsif ($input->{fh}) {
1229 my $fd = fileno($input->{fh});
1230 unless (defined $fd) {
1231 $self->_set_error("Handle in fh option not opened");
1234 return io_new_fd($fd);
1236 elsif ($input->{file}) {
1237 my $file = IO::File->new($input->{file}, "r");
1239 $self->_set_error("Could not open $input->{file}: $!");
1243 return (io_new_fd(fileno($file)), $file);
1245 elsif ($input->{data}) {
1246 return io_new_buffer($input->{data});
1248 elsif ($input->{callback} || $input->{readcb}) {
1249 if (!$input->{seekcb}) {
1250 $self->_set_error("Need a seekcb parameter");
1252 if ($input->{maxbuffer}) {
1253 return io_new_cb($input->{writecb},
1254 $input->{callback} || $input->{readcb},
1255 $input->{seekcb}, $input->{closecb},
1256 $input->{maxbuffer});
1259 return io_new_cb($input->{writecb},
1260 $input->{callback} || $input->{readcb},
1261 $input->{seekcb}, $input->{closecb});
1265 $self->_set_error("file/fd/fh/data/callback parameter missing");
1270 sub _get_writer_io {
1271 my ($self, $input, $type) = @_;
1274 return $input->{io};
1276 elsif ($input->{fd}) {
1277 return io_new_fd($input->{fd});
1279 elsif ($input->{fh}) {
1280 my $fd = fileno($input->{fh});
1281 unless (defined $fd) {
1282 $self->_set_error("Handle in fh option not opened");
1286 my $oldfh = select($input->{fh});
1287 # flush anything that's buffered, and make sure anything else is flushed
1290 return io_new_fd($fd);
1292 elsif ($input->{file}) {
1293 my $fh = new IO::File($input->{file},"w+");
1295 $self->_set_error("Could not open file $input->{file}: $!");
1298 binmode($fh) or die;
1299 return (io_new_fd(fileno($fh)), $fh);
1301 elsif ($input->{data}) {
1302 return io_new_bufchain();
1304 elsif ($input->{callback} || $input->{writecb}) {
1305 if ($input->{maxbuffer}) {
1306 return io_new_cb($input->{callback} || $input->{writecb},
1308 $input->{seekcb}, $input->{closecb},
1309 $input->{maxbuffer});
1312 return io_new_cb($input->{callback} || $input->{writecb},
1314 $input->{seekcb}, $input->{closecb});
1318 $self->_set_error("file/fd/fh/data/callback parameter missing");
1323 # Read an image from file
1329 if (defined($self->{IMG})) {
1330 # let IIM_DESTROY do the destruction, since the image may be
1331 # referenced from elsewhere
1332 #i_img_destroy($self->{IMG});
1333 undef($self->{IMG});
1336 my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
1338 unless ($input{'type'}) {
1339 $input{'type'} = i_test_format_probe($IO, -1);
1342 unless ($input{'type'}) {
1343 $self->_set_error('type parameter missing and not possible to guess from extension');
1347 _reader_autoload($input{type});
1349 if ($readers{$input{type}} && $readers{$input{type}}{single}) {
1350 return $readers{$input{type}}{single}->($self, $IO, %input);
1353 unless ($formats_low{$input{'type'}}) {
1354 my $read_types = join ', ', sort Imager->read_types();
1355 $self->_set_error("format '$input{'type'}' not supported - formats $read_types available for reading");
1359 my $allow_incomplete = $input{allow_incomplete};
1360 defined $allow_incomplete or $allow_incomplete = 0;
1362 if ( $input{'type'} eq 'pnm' ) {
1363 $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
1364 if ( !defined($self->{IMG}) ) {
1365 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
1368 $self->{DEBUG} && print "loading a pnm file\n";
1372 if ( $input{'type'} eq 'bmp' ) {
1373 $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
1374 if ( !defined($self->{IMG}) ) {
1375 $self->{ERRSTR}=$self->_error_as_msg();
1378 $self->{DEBUG} && print "loading a bmp file\n";
1381 if ( $input{'type'} eq 'gif' ) {
1382 if ($input{colors} && !ref($input{colors})) {
1383 # must be a reference to a scalar that accepts the colour map
1384 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
1387 if ($input{'gif_consolidate'}) {
1388 if ($input{colors}) {
1390 ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
1392 ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
1396 $self->{IMG} =i_readgif_wiol( $IO );
1400 my $page = $input{'page'};
1401 defined $page or $page = 0;
1402 $self->{IMG} = i_readgif_single_wiol( $IO, $page );
1403 if ($self->{IMG} && $input{colors}) {
1404 ${ $input{colors} } =
1405 [ i_getcolors($self->{IMG}, 0, i_colorcount($self->{IMG})) ];
1409 if ( !defined($self->{IMG}) ) {
1410 $self->{ERRSTR}=$self->_error_as_msg();
1413 $self->{DEBUG} && print "loading a gif file\n";
1416 if ( $input{'type'} eq 'tga' ) {
1417 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
1418 if ( !defined($self->{IMG}) ) {
1419 $self->{ERRSTR}=$self->_error_as_msg();
1422 $self->{DEBUG} && print "loading a tga file\n";
1425 if ( $input{'type'} eq 'raw' ) {
1426 unless ( $input{xsize} && $input{ysize} ) {
1427 $self->_set_error('missing xsize or ysize parameter for raw');
1431 my $interleave = _first($input{raw_interleave}, $input{interleave});
1432 unless (defined $interleave) {
1433 my @caller = caller;
1434 warn "read(type => 'raw') $caller[2] line $caller[1]: supply interleave or raw_interleave for future compatibility\n";
1437 my $data_ch = _first($input{raw_datachannels}, $input{datachannels}, 3);
1438 my $store_ch = _first($input{raw_storechannels}, $input{storechannels}, 3);
1440 $self->{IMG} = i_readraw_wiol( $IO,
1446 if ( !defined($self->{IMG}) ) {
1447 $self->{ERRSTR}=$self->_error_as_msg();
1450 $self->{DEBUG} && print "loading a raw file\n";
1456 sub register_reader {
1457 my ($class, %opts) = @_;
1460 or die "register_reader called with no type parameter\n";
1462 my $type = $opts{type};
1464 defined $opts{single} || defined $opts{multiple}
1465 or die "register_reader called with no single or multiple parameter\n";
1467 $readers{$type} = { };
1468 if ($opts{single}) {
1469 $readers{$type}{single} = $opts{single};
1471 if ($opts{multiple}) {
1472 $readers{$type}{multiple} = $opts{multiple};
1478 sub register_writer {
1479 my ($class, %opts) = @_;
1482 or die "register_writer called with no type parameter\n";
1484 my $type = $opts{type};
1486 defined $opts{single} || defined $opts{multiple}
1487 or die "register_writer called with no single or multiple parameter\n";
1489 $writers{$type} = { };
1490 if ($opts{single}) {
1491 $writers{$type}{single} = $opts{single};
1493 if ($opts{multiple}) {
1494 $writers{$type}{multiple} = $opts{multiple};
1505 grep($file_formats{$_}, keys %formats),
1506 qw(ico sgi), # formats not handled directly, but supplied with Imager
1517 grep($file_formats{$_}, keys %formats),
1518 qw(ico sgi), # formats not handled directly, but supplied with Imager
1524 # probes for an Imager::File::whatever module
1525 sub _reader_autoload {
1528 return if $formats_low{$type} || $readers{$type};
1530 return unless $type =~ /^\w+$/;
1532 my $file = "Imager/File/\U$type\E.pm";
1534 unless ($attempted_to_load{$file}) {
1536 ++$attempted_to_load{$file};
1540 # try to get a reader specific module
1541 my $file = "Imager/File/\U$type\EReader.pm";
1542 unless ($attempted_to_load{$file}) {
1544 ++$attempted_to_load{$file};
1552 # probes for an Imager::File::whatever module
1553 sub _writer_autoload {
1556 return if $formats_low{$type} || $readers{$type};
1558 return unless $type =~ /^\w+$/;
1560 my $file = "Imager/File/\U$type\E.pm";
1562 unless ($attempted_to_load{$file}) {
1564 ++$attempted_to_load{$file};
1568 # try to get a writer specific module
1569 my $file = "Imager/File/\U$type\EWriter.pm";
1570 unless ($attempted_to_load{$file}) {
1572 ++$attempted_to_load{$file};
1580 sub _fix_gif_positions {
1581 my ($opts, $opt, $msg, @imgs) = @_;
1583 my $positions = $opts->{'gif_positions'};
1585 for my $pos (@$positions) {
1586 my ($x, $y) = @$pos;
1587 my $img = $imgs[$index++];
1588 $img->settag(name=>'gif_left', value=>$x);
1589 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1591 $$msg .= "replaced with the gif_left and gif_top tags";
1596 gif_each_palette=>'gif_local_map',
1597 interlace => 'gif_interlace',
1598 gif_delays => 'gif_delay',
1599 gif_positions => \&_fix_gif_positions,
1600 gif_loop_count => 'gif_loop',
1603 # options that should be converted to colors
1604 my %color_opts = map { $_ => 1 } qw/i_background/;
1607 my ($self, $opts, $prefix, @imgs) = @_;
1609 for my $opt (keys %$opts) {
1611 if ($obsolete_opts{$opt}) {
1612 my $new = $obsolete_opts{$opt};
1613 my $msg = "Obsolete option $opt ";
1615 $new->($opts, $opt, \$msg, @imgs);
1618 $msg .= "replaced with the $new tag ";
1621 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1622 warn $msg if $warn_obsolete && $^W;
1624 next unless $tagname =~ /^\Q$prefix/;
1625 my $value = $opts->{$opt};
1626 if ($color_opts{$opt}) {
1627 $value = _color($value);
1629 $self->_set_error($Imager::ERRSTR);
1634 if (UNIVERSAL::isa($value, "Imager::Color")) {
1635 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1636 for my $img (@imgs) {
1637 $img->settag(name=>$tagname, value=>$tag);
1640 elsif (ref($value) eq 'ARRAY') {
1641 for my $i (0..$#$value) {
1642 my $val = $value->[$i];
1644 if (UNIVERSAL::isa($val, "Imager::Color")) {
1645 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1647 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1650 $self->_set_error("Unknown reference type " . ref($value) .
1651 " supplied in array for $opt");
1657 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1662 $self->_set_error("Unknown reference type " . ref($value) .
1663 " supplied for $opt");
1668 # set it as a tag for every image
1669 for my $img (@imgs) {
1670 $img->settag(name=>$tagname, value=>$value);
1678 # Write an image to file
1681 my %input=(jpegquality=>75,
1691 $self->_set_opts(\%input, "i_", $self)
1694 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1696 if (!$input{'type'} and $input{file}) {
1697 $input{'type'}=$FORMATGUESS->($input{file});
1699 if (!$input{'type'}) {
1700 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1704 _writer_autoload($input{type});
1707 if ($writers{$input{type}} && $writers{$input{type}}{single}) {
1708 ($IO, $fh) = $self->_get_writer_io(\%input, $input{'type'})
1711 $writers{$input{type}}{single}->($self, $IO, %input)
1715 if (!$formats_low{$input{'type'}}) {
1716 my $write_types = join ', ', sort Imager->write_types();
1717 $self->_set_error("format '$input{'type'}' not supported - formats $write_types available for writing");
1721 ($IO, $fh) = $self->_get_writer_io(\%input, $input{'type'})
1724 if ( $input{'type'} eq 'pnm' ) {
1725 $self->_set_opts(\%input, "pnm_", $self)
1727 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1728 $self->{ERRSTR} = $self->_error_as_msg();
1731 $self->{DEBUG} && print "writing a pnm file\n";
1732 } elsif ( $input{'type'} eq 'raw' ) {
1733 $self->_set_opts(\%input, "raw_", $self)
1735 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1736 $self->{ERRSTR} = $self->_error_as_msg();
1739 $self->{DEBUG} && print "writing a raw file\n";
1740 } elsif ( $input{'type'} eq 'jpeg' ) {
1741 $self->_set_opts(\%input, "jpeg_", $self)
1743 $self->_set_opts(\%input, "exif_", $self)
1745 if ( !i_writejpeg_wiol($self->{IMG}, $IO, $input{jpegquality})) {
1746 $self->{ERRSTR} = $self->_error_as_msg();
1749 $self->{DEBUG} && print "writing a jpeg file\n";
1750 } elsif ( $input{'type'} eq 'bmp' ) {
1751 $self->_set_opts(\%input, "bmp_", $self)
1753 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1754 $self->{ERRSTR} = $self->_error_as_msg;
1757 $self->{DEBUG} && print "writing a bmp file\n";
1758 } elsif ( $input{'type'} eq 'tga' ) {
1759 $self->_set_opts(\%input, "tga_", $self)
1762 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1763 $self->{ERRSTR}=$self->_error_as_msg();
1766 $self->{DEBUG} && print "writing a tga file\n";
1767 } elsif ( $input{'type'} eq 'gif' ) {
1768 $self->_set_opts(\%input, "gif_", $self)
1770 # compatibility with the old interfaces
1771 if ($input{gifquant} eq 'lm') {
1772 $input{make_colors} = 'addi';
1773 $input{translate} = 'perturb';
1774 $input{perturb} = $input{lmdither};
1775 } elsif ($input{gifquant} eq 'gen') {
1776 # just pass options through
1778 $input{make_colors} = 'webmap'; # ignored
1779 $input{translate} = 'giflib';
1781 if (!i_writegif_wiol($IO, \%input, $self->{IMG})) {
1782 $self->{ERRSTR} = $self->_error_as_msg;
1788 if (exists $input{'data'}) {
1789 my $data = io_slurp($IO);
1791 $self->{ERRSTR}='Could not slurp from buffer';
1794 ${$input{data}} = $data;
1800 my ($class, $opts, @images) = @_;
1802 my $type = $opts->{type};
1804 if (!$type && $opts->{'file'}) {
1805 $type = $FORMATGUESS->($opts->{'file'});
1808 $class->_set_error('type parameter missing and not possible to guess from extension');
1811 # translate to ImgRaw
1812 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1813 $class->_set_error('Usage: Imager->write_multi({ options }, @images)');
1816 $class->_set_opts($opts, "i_", @images)
1818 my @work = map $_->{IMG}, @images;
1820 _writer_autoload($type);
1823 if ($writers{$type} && $writers{$type}{multiple}) {
1824 ($IO, $file) = $class->_get_writer_io($opts, $type)
1827 $writers{$type}{multiple}->($class, $IO, $opts, @images)
1831 if (!$formats{$type}) {
1832 my $write_types = join ', ', sort Imager->write_types();
1833 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
1837 ($IO, $file) = $class->_get_writer_io($opts, $type)
1840 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
1844 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
1849 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
1855 if (exists $opts->{'data'}) {
1856 my $data = io_slurp($IO);
1858 Imager->_set_error('Could not slurp from buffer');
1861 ${$opts->{data}} = $data;
1866 # read multiple images from a file
1868 my ($class, %opts) = @_;
1870 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
1873 my $type = $opts{'type'};
1875 $type = i_test_format_probe($IO, -1);
1878 if ($opts{file} && !$type) {
1880 $type = $FORMATGUESS->($opts{file});
1884 $ERRSTR = "No type parameter supplied and it couldn't be guessed";
1888 _reader_autoload($type);
1890 if ($readers{$type} && $readers{$type}{multiple}) {
1891 return $readers{$type}{multiple}->($IO, %opts);
1894 unless ($formats{$type}) {
1895 my $read_types = join ', ', sort Imager->read_types();
1896 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
1901 if ($type eq 'pnm') {
1902 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
1905 my $img = Imager->new;
1906 if ($img->read(%opts, io => $IO, type => $type)) {
1909 Imager->_set_error($img->errstr);
1914 $ERRSTR = _error_as_msg();
1918 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1922 # Destroy an Imager object
1926 # delete $instances{$self};
1927 if (defined($self->{IMG})) {
1928 # the following is now handled by the XS DESTROY method for
1929 # Imager::ImgRaw object
1930 # Re-enabling this will break virtual images
1931 # tested for in t/t020masked.t
1932 # i_img_destroy($self->{IMG});
1933 undef($self->{IMG});
1935 # print "Destroy Called on an empty image!\n"; # why did I put this here??
1939 # Perform an inplace filter of an image
1940 # that is the image will be overwritten with the data
1946 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1948 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
1950 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
1951 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
1954 if ($filters{$input{'type'}}{names}) {
1955 my $names = $filters{$input{'type'}}{names};
1956 for my $name (keys %$names) {
1957 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
1958 $input{$name} = $names->{$name}{$input{$name}};
1962 if (defined($filters{$input{'type'}}{defaults})) {
1963 %hsh=( image => $self->{IMG},
1965 %{$filters{$input{'type'}}{defaults}},
1968 %hsh=( image => $self->{IMG},
1973 my @cs=@{$filters{$input{'type'}}{callseq}};
1976 if (!defined($hsh{$_})) {
1977 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
1982 local $SIG{__DIE__}; # we don't want this processed by confess, etc
1983 &{$filters{$input{'type'}}{callsub}}(%hsh);
1986 chomp($self->{ERRSTR} = $@);
1992 $self->{DEBUG} && print "callseq is: @cs\n";
1993 $self->{DEBUG} && print "matching callseq is: @b\n";
1998 sub register_filter {
2000 my %hsh = ( defaults => {}, @_ );
2003 or die "register_filter() with no type\n";
2004 defined $hsh{callsub}
2005 or die "register_filter() with no callsub\n";
2006 defined $hsh{callseq}
2007 or die "register_filter() with no callseq\n";
2009 exists $filters{$hsh{type}}
2012 $filters{$hsh{type}} = \%hsh;
2017 sub scale_calculate {
2020 my %opts = ('type'=>'max', @_);
2022 # none of these should be references
2023 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2024 if (defined $opts{$name} && ref $opts{$name}) {
2025 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2030 my ($x_scale, $y_scale);
2031 my $width = $opts{width};
2032 my $height = $opts{height};
2034 defined $width or $width = $self->getwidth;
2035 defined $height or $height = $self->getheight;
2038 unless (defined $width && defined $height) {
2039 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2044 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2045 $x_scale = $opts{'xscalefactor'};
2046 $y_scale = $opts{'yscalefactor'};
2048 elsif ($opts{'xscalefactor'}) {
2049 $x_scale = $opts{'xscalefactor'};
2050 $y_scale = $opts{'scalefactor'} || $x_scale;
2052 elsif ($opts{'yscalefactor'}) {
2053 $y_scale = $opts{'yscalefactor'};
2054 $x_scale = $opts{'scalefactor'} || $y_scale;
2057 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2060 # work out the scaling
2061 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2062 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2063 $opts{ypixels} / $height );
2064 if ($opts{'type'} eq 'min') {
2065 $x_scale = $y_scale = _min($xpix,$ypix);
2067 elsif ($opts{'type'} eq 'max') {
2068 $x_scale = $y_scale = _max($xpix,$ypix);
2070 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2075 $self->_set_error('invalid value for type parameter');
2078 } elsif ($opts{xpixels}) {
2079 $x_scale = $y_scale = $opts{xpixels} / $width;
2081 elsif ($opts{ypixels}) {
2082 $x_scale = $y_scale = $opts{ypixels}/$height;
2084 elsif ($opts{constrain} && ref $opts{constrain}
2085 && $opts{constrain}->can('constrain')) {
2086 # we've been passed an Image::Math::Constrain object or something
2087 # that looks like one
2089 (undef, undef, $scalefactor)
2090 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2091 unless ($scalefactor) {
2092 $self->_set_error('constrain method failed on constrain parameter');
2095 $x_scale = $y_scale = $scalefactor;
2098 my $new_width = int($x_scale * $width + 0.5);
2099 $new_width > 0 or $new_width = 1;
2100 my $new_height = int($y_scale * $height + 0.5);
2101 $new_height > 0 or $new_height = 1;
2103 return ($x_scale, $y_scale, $new_width, $new_height);
2107 # Scale an image to requested size and return the scaled version
2111 my %opts = (qtype=>'normal' ,@_);
2112 my $img = Imager->new();
2113 my $tmp = Imager->new();
2115 unless (defined wantarray) {
2116 my @caller = caller;
2117 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2121 unless ($self->{IMG}) {
2122 $self->_set_error('empty input image');
2126 my ($x_scale, $y_scale, $new_width, $new_height) =
2127 $self->scale_calculate(%opts)
2130 if ($opts{qtype} eq 'normal') {
2131 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2132 if ( !defined($tmp->{IMG}) ) {
2133 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2136 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2137 if ( !defined($img->{IMG}) ) {
2138 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2144 elsif ($opts{'qtype'} eq 'preview') {
2145 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2146 if ( !defined($img->{IMG}) ) {
2147 $self->{ERRSTR}='unable to scale image';
2152 elsif ($opts{'qtype'} eq 'mixing') {
2153 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2154 unless ($img->{IMG}) {
2155 $self->_set_error(Imager->_error_as_msg);
2161 $self->_set_error('invalid value for qtype parameter');
2166 # Scales only along the X axis
2170 my %opts = ( scalefactor=>0.5, @_ );
2172 unless (defined wantarray) {
2173 my @caller = caller;
2174 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2178 unless ($self->{IMG}) {
2179 $self->{ERRSTR} = 'empty input image';
2183 my $img = Imager->new();
2185 my $scalefactor = $opts{scalefactor};
2187 if ($opts{pixels}) {
2188 $scalefactor = $opts{pixels} / $self->getwidth();
2191 unless ($self->{IMG}) {
2192 $self->{ERRSTR}='empty input image';
2196 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2198 if ( !defined($img->{IMG}) ) {
2199 $self->{ERRSTR} = 'unable to scale image';
2206 # Scales only along the Y axis
2210 my %opts = ( scalefactor => 0.5, @_ );
2212 unless (defined wantarray) {
2213 my @caller = caller;
2214 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2218 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2220 my $img = Imager->new();
2222 my $scalefactor = $opts{scalefactor};
2224 if ($opts{pixels}) {
2225 $scalefactor = $opts{pixels} / $self->getheight();
2228 unless ($self->{IMG}) {
2229 $self->{ERRSTR} = 'empty input image';
2232 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2234 if ( !defined($img->{IMG}) ) {
2235 $self->{ERRSTR} = 'unable to scale image';
2242 # Transform returns a spatial transformation of the input image
2243 # this moves pixels to a new location in the returned image.
2244 # NOTE - should make a utility function to check transforms for
2249 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2251 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2253 # print Dumper(\%opts);
2256 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2258 eval ("use Affix::Infix2Postfix;");
2261 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2264 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2265 {op=>'-',trans=>'Sub'},
2266 {op=>'*',trans=>'Mult'},
2267 {op=>'/',trans=>'Div'},
2268 {op=>'-','type'=>'unary',trans=>'u-'},
2270 {op=>'func','type'=>'unary'}],
2271 'grouping'=>[qw( \( \) )],
2272 'func'=>[qw( sin cos )],
2277 @xt=$I2P->translate($opts{'xexpr'});
2278 @yt=$I2P->translate($opts{'yexpr'});
2280 $numre=$I2P->{'numre'};
2283 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2284 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2285 @{$opts{'parm'}}=@pt;
2288 # print Dumper(\%opts);
2290 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2291 $self->{ERRSTR}='transform: no xopcodes given.';
2295 @op=@{$opts{'xopcodes'}};
2297 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2298 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2301 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2307 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2308 $self->{ERRSTR}='transform: no yopcodes given.';
2312 @op=@{$opts{'yopcodes'}};
2314 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2315 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2318 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2323 if ( !exists $opts{'parm'}) {
2324 $self->{ERRSTR}='transform: no parameter arg given.';
2328 # print Dumper(\@ropx);
2329 # print Dumper(\@ropy);
2330 # print Dumper(\@ropy);
2332 my $img = Imager->new();
2333 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2334 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2340 my ($opts, @imgs) = @_;
2342 require "Imager/Expr.pm";
2344 $opts->{variables} = [ qw(x y) ];
2345 my ($width, $height) = @{$opts}{qw(width height)};
2347 $width ||= $imgs[0]->getwidth();
2348 $height ||= $imgs[0]->getheight();
2350 for my $img (@imgs) {
2351 $opts->{constants}{"w$img_num"} = $img->getwidth();
2352 $opts->{constants}{"h$img_num"} = $img->getheight();
2353 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2354 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2359 $opts->{constants}{w} = $width;
2360 $opts->{constants}{cx} = $width/2;
2363 $Imager::ERRSTR = "No width supplied";
2367 $opts->{constants}{h} = $height;
2368 $opts->{constants}{cy} = $height/2;
2371 $Imager::ERRSTR = "No height supplied";
2374 my $code = Imager::Expr->new($opts);
2376 $Imager::ERRSTR = Imager::Expr::error();
2379 my $channels = $opts->{channels} || 3;
2380 unless ($channels >= 1 && $channels <= 4) {
2381 return Imager->_set_error("channels must be an integer between 1 and 4");
2384 my $img = Imager->new();
2385 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2386 $channels, $code->code(),
2387 $code->nregs(), $code->cregs(),
2388 [ map { $_->{IMG} } @imgs ]);
2389 if (!defined $img->{IMG}) {
2390 $Imager::ERRSTR = Imager->_error_as_msg();
2401 unless ($self->{IMG}) {
2402 $self->{ERRSTR}='empty input image';
2405 unless ($opts{src} && $opts{src}->{IMG}) {
2406 $self->{ERRSTR}='empty input image for src';
2410 %opts = (src_minx => 0,
2412 src_maxx => $opts{src}->getwidth(),
2413 src_maxy => $opts{src}->getheight(),
2417 defined $tx or $tx = $opts{left};
2418 defined $tx or $tx = 0;
2421 defined $ty or $ty = $opts{top};
2422 defined $ty or $ty = 0;
2424 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2425 $opts{src_minx}, $opts{src_miny},
2426 $opts{src_maxx}, $opts{src_maxy})) {
2427 $self->_set_error($self->_error_as_msg());
2444 unless ($self->{IMG}) {
2445 $self->_set_error("compose: empty input image");
2449 unless ($opts{src}) {
2450 $self->_set_error("compose: src parameter missing");
2454 unless ($opts{src}{IMG}) {
2455 $self->_set_error("compose: src parameter empty image");
2458 my $src = $opts{src};
2460 my $left = $opts{left};
2461 defined $left or $left = $opts{tx};
2462 defined $left or $left = 0;
2464 my $top = $opts{top};
2465 defined $top or $top = $opts{ty};
2466 defined $top or $top = 0;
2468 my $src_left = $opts{src_left};
2469 defined $src_left or $src_left = $opts{src_minx};
2470 defined $src_left or $src_left = 0;
2472 my $src_top = $opts{src_top};
2473 defined $src_top or $src_top = $opts{src_miny};
2474 defined $src_top or $src_top = 0;
2476 my $width = $opts{width};
2477 if (!defined $width && defined $opts{src_maxx}) {
2478 $width = $opts{src_maxx} - $src_left;
2480 defined $width or $width = $src->getwidth() - $src_left;
2482 my $height = $opts{height};
2483 if (!defined $height && defined $opts{src_maxy}) {
2484 $height = $opts{src_maxy} - $src_top;
2486 defined $height or $height = $src->getheight() - $src_top;
2488 my $combine = $self->_combine($opts{combine}, 'normal');
2491 unless ($opts{mask}{IMG}) {
2492 $self->_set_error("compose: mask parameter empty image");
2496 my $mask_left = $opts{mask_left};
2497 defined $mask_left or $mask_left = $opts{mask_minx};
2498 defined $mask_left or $mask_left = 0;
2500 my $mask_top = $opts{mask_top};
2501 defined $mask_top or $mask_top = $opts{mask_miny};
2502 defined $mask_top or $mask_top = 0;
2504 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2505 $left, $top, $src_left, $src_top,
2506 $mask_left, $mask_top, $width, $height,
2507 $combine, $opts{opacity})) {
2508 $self->_set_error(Imager->_error_as_msg);
2513 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2514 $width, $height, $combine, $opts{opacity})) {
2515 $self->_set_error(Imager->_error_as_msg);
2526 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2528 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2529 $dir = $xlate{$opts{'dir'}};
2530 return $self if i_flipxy($self->{IMG}, $dir);
2538 unless (defined wantarray) {
2539 my @caller = caller;
2540 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2544 if (defined $opts{right}) {
2545 my $degrees = $opts{right};
2547 $degrees += 360 * int(((-$degrees)+360)/360);
2549 $degrees = $degrees % 360;
2550 if ($degrees == 0) {
2551 return $self->copy();
2553 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2554 my $result = Imager->new();
2555 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2559 $self->{ERRSTR} = $self->_error_as_msg();
2564 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2568 elsif (defined $opts{radians} || defined $opts{degrees}) {
2569 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
2571 my $back = $opts{back};
2572 my $result = Imager->new;
2574 $back = _color($back);
2576 $self->_set_error(Imager->errstr);
2580 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2583 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2585 if ($result->{IMG}) {
2589 $self->{ERRSTR} = $self->_error_as_msg();
2594 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2599 sub matrix_transform {
2603 unless (defined wantarray) {
2604 my @caller = caller;
2605 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2609 if ($opts{matrix}) {
2610 my $xsize = $opts{xsize} || $self->getwidth;
2611 my $ysize = $opts{ysize} || $self->getheight;
2613 my $result = Imager->new;
2615 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2616 $opts{matrix}, $opts{back})
2620 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2628 $self->{ERRSTR} = "matrix parameter required";
2634 *yatf = \&matrix_transform;
2636 # These two are supported for legacy code only
2639 return Imager::Color->new(@_);
2643 return Imager::Color::set(@_);
2646 # Draws a box between the specified corner points.
2649 my $raw = $self->{IMG};
2652 $self->{ERRSTR}='empty input image';
2658 my ($xmin, $ymin, $xmax, $ymax);
2659 if (exists $opts{'box'}) {
2660 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2661 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2662 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2663 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2666 defined($xmin = $opts{xmin}) or $xmin = 0;
2667 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2668 defined($ymin = $opts{ymin}) or $ymin = 0;
2669 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2672 if ($opts{filled}) {
2673 my $color = $opts{'color'};
2675 if (defined $color) {
2676 unless (_is_color_object($color)) {
2677 $color = _color($color);
2679 $self->{ERRSTR} = $Imager::ERRSTR;
2685 $color = i_color_new(255,255,255,255);
2688 if ($color->isa("Imager::Color")) {
2689 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2692 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2695 elsif ($opts{fill}) {
2696 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2697 # assume it's a hash ref
2698 require 'Imager/Fill.pm';
2699 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2700 $self->{ERRSTR} = $Imager::ERRSTR;
2704 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2707 my $color = $opts{'color'};
2708 if (defined $color) {
2709 unless (_is_color_object($color)) {
2710 $color = _color($color);
2712 $self->{ERRSTR} = $Imager::ERRSTR;
2718 $color = i_color_new(255, 255, 255, 255);
2721 $self->{ERRSTR} = $Imager::ERRSTR;
2724 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2732 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2733 my $dflcl= [ 255, 255, 255, 255];
2738 'r'=>_min($self->getwidth(),$self->getheight())/3,
2739 'x'=>$self->getwidth()/2,
2740 'y'=>$self->getheight()/2,
2747 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2748 # assume it's a hash ref
2749 require 'Imager/Fill.pm';
2750 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2751 $self->{ERRSTR} = $Imager::ERRSTR;
2755 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2756 $opts{'d2'}, $opts{fill}{fill});
2758 elsif ($opts{filled}) {
2759 my $color = _color($opts{'color'});
2761 $self->{ERRSTR} = $Imager::ERRSTR;
2764 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2765 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2769 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2770 $opts{'d1'}, $opts{'d2'}, $color);
2774 my $color = _color($opts{'color'});
2775 if ($opts{d2} - $opts{d1} >= 360) {
2776 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
2779 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
2785 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2786 # assume it's a hash ref
2787 require 'Imager/Fill.pm';
2788 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2789 $self->{ERRSTR} = $Imager::ERRSTR;
2793 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2794 $opts{'d2'}, $opts{fill}{fill});
2797 my $color = _color($opts{'color'});
2799 $self->{ERRSTR} = $Imager::ERRSTR;
2802 if ($opts{filled}) {
2803 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2804 $opts{'d1'}, $opts{'d2'}, $color);
2807 if ($opts{d1} == 0 && $opts{d2} == 361) {
2808 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
2811 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
2817 $self->_set_error($self->_error_as_msg);
2824 # Draws a line from one point to the other
2825 # the endpoint is set if the endp parameter is set which it is by default.
2826 # to turn of the endpoint being set use endp=>0 when calling line.
2830 my $dflcl=i_color_new(0,0,0,0);
2831 my %opts=(color=>$dflcl,
2834 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2836 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
2837 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
2839 my $color = _color($opts{'color'});
2841 $self->{ERRSTR} = $Imager::ERRSTR;
2845 $opts{antialias} = $opts{aa} if defined $opts{aa};
2846 if ($opts{antialias}) {
2847 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2848 $color, $opts{endp});
2850 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2851 $color, $opts{endp});
2856 # Draws a line between an ordered set of points - It more or less just transforms this
2857 # into a list of lines.
2861 my ($pt,$ls,@points);
2862 my $dflcl=i_color_new(0,0,0,0);
2863 my %opts=(color=>$dflcl,@_);
2865 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2867 if (exists($opts{points})) { @points=@{$opts{points}}; }
2868 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
2869 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
2872 # print Dumper(\@points);
2874 my $color = _color($opts{'color'});
2876 $self->{ERRSTR} = $Imager::ERRSTR;
2879 $opts{antialias} = $opts{aa} if defined $opts{aa};
2880 if ($opts{antialias}) {
2883 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
2890 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
2900 my ($pt,$ls,@points);
2901 my $dflcl = i_color_new(0,0,0,0);
2902 my %opts = (color=>$dflcl, @_);
2904 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2906 if (exists($opts{points})) {
2907 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
2908 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
2911 if (!exists $opts{'x'} or !exists $opts{'y'}) {
2912 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
2915 if ($opts{'fill'}) {
2916 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
2917 # assume it's a hash ref
2918 require 'Imager/Fill.pm';
2919 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
2920 $self->{ERRSTR} = $Imager::ERRSTR;
2924 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
2925 $opts{'fill'}{'fill'});
2928 my $color = _color($opts{'color'});
2930 $self->{ERRSTR} = $Imager::ERRSTR;
2933 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
2940 # this the multipoint bezier curve
2941 # this is here more for testing that actual usage since
2942 # this is not a good algorithm. Usually the curve would be
2943 # broken into smaller segments and each done individually.
2947 my ($pt,$ls,@points);
2948 my $dflcl=i_color_new(0,0,0,0);
2949 my %opts=(color=>$dflcl,@_);
2951 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2953 if (exists $opts{points}) {
2954 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
2955 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
2958 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
2959 $self->{ERRSTR}='Missing or invalid points.';
2963 my $color = _color($opts{'color'});
2965 $self->{ERRSTR} = $Imager::ERRSTR;
2968 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
2974 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
2977 unless (exists $opts{'x'} && exists $opts{'y'}) {
2978 $self->{ERRSTR} = "missing seed x and y parameters";
2982 if ($opts{border}) {
2983 my $border = _color($opts{border});
2985 $self->_set_error($Imager::ERRSTR);
2989 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2990 # assume it's a hash ref
2991 require Imager::Fill;
2992 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2993 $self->{ERRSTR} = $Imager::ERRSTR;
2997 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
2998 $opts{fill}{fill}, $border);
3001 my $color = _color($opts{'color'});
3003 $self->{ERRSTR} = $Imager::ERRSTR;
3006 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3013 $self->{ERRSTR} = $self->_error_as_msg();
3019 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3020 # assume it's a hash ref
3021 require 'Imager/Fill.pm';
3022 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3023 $self->{ERRSTR} = $Imager::ERRSTR;
3027 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3030 my $color = _color($opts{'color'});
3032 $self->{ERRSTR} = $Imager::ERRSTR;
3035 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3041 $self->{ERRSTR} = $self->_error_as_msg();
3048 my ($self, %opts) = @_;
3050 my $color = $opts{color};
3051 unless (defined $color) {
3052 $color = $self->{fg};
3053 defined $color or $color = NC(255, 255, 255);
3056 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3057 $color = _color($color)
3061 unless (exists $opts{'x'} && exists $opts{'y'}) {
3062 $self->{ERRSTR} = 'missing x and y parameters';
3068 if (ref $x && ref $y) {
3069 unless (@$x == @$y) {
3070 $self->{ERRSTR} = 'length of x and y mismatch';
3074 if ($color->isa('Imager::Color')) {
3075 for my $i (0..$#{$opts{'x'}}) {
3076 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3081 for my $i (0..$#{$opts{'x'}}) {
3082 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3090 if ($color->isa('Imager::Color')) {
3091 i_ppix($self->{IMG}, $x, $y, $color)
3095 i_ppixf($self->{IMG}, $x, $y, $color)
3106 my %opts = ( "type"=>'8bit', @_);
3108 unless (exists $opts{'x'} && exists $opts{'y'}) {
3109 $self->{ERRSTR} = 'missing x and y parameters';
3115 if (ref $x && ref $y) {
3116 unless (@$x == @$y) {
3117 $self->{ERRSTR} = 'length of x and y mismatch';
3121 if ($opts{"type"} eq '8bit') {
3122 for my $i (0..$#{$opts{'x'}}) {
3123 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3127 for my $i (0..$#{$opts{'x'}}) {
3128 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3131 return wantarray ? @result : \@result;
3134 if ($opts{"type"} eq '8bit') {
3135 return i_get_pixel($self->{IMG}, $x, $y);
3138 return i_gpixf($self->{IMG}, $x, $y);
3147 my %opts = ( type => '8bit', x=>0, @_);
3149 $self->_valid_image or return;
3151 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3153 unless (defined $opts{'y'}) {
3154 $self->_set_error("missing y parameter");
3158 if ($opts{type} eq '8bit') {
3159 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3162 elsif ($opts{type} eq 'float') {
3163 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3166 elsif ($opts{type} eq 'index') {
3167 unless (i_img_type($self->{IMG})) {
3168 $self->_set_error("type => index only valid on paletted images");
3171 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3175 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3182 my %opts = ( x=>0, @_);
3184 $self->_valid_image or return;
3186 unless (defined $opts{'y'}) {
3187 $self->_set_error("missing y parameter");
3192 if (ref $opts{pixels} && @{$opts{pixels}}) {
3193 # try to guess the type
3194 if ($opts{pixels}[0]->isa('Imager::Color')) {
3195 $opts{type} = '8bit';
3197 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3198 $opts{type} = 'float';
3201 $self->_set_error("missing type parameter and could not guess from pixels");
3207 $opts{type} = '8bit';
3211 if ($opts{type} eq '8bit') {
3212 if (ref $opts{pixels}) {
3213 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3216 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3219 elsif ($opts{type} eq 'float') {
3220 if (ref $opts{pixels}) {
3221 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3224 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3227 elsif ($opts{type} eq 'index') {
3228 if (ref $opts{pixels}) {
3229 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3232 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3236 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3243 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3245 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3247 unless (defined $opts{'y'}) {
3248 $self->_set_error("missing y parameter");
3252 unless ($opts{channels}) {
3253 $opts{channels} = [ 0 .. $self->getchannels()-1 ];
3256 if ($opts{target}) {
3257 my $target = $opts{target};
3258 my $offset = $opts{offset};
3259 if ($opts{type} eq '8bit') {
3260 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3261 $opts{y}, @{$opts{channels}})
3263 @{$target}{$offset .. $offset + @samples - 1} = @samples;
3264 return scalar(@samples);
3266 elsif ($opts{type} eq 'float') {
3267 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3268 $opts{y}, @{$opts{channels}});
3269 @{$target}{$offset .. $offset + @samples - 1} = @samples;
3270 return scalar(@samples);
3272 elsif ($opts{type} =~ /^(\d+)bit$/) {
3276 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3277 $opts{y}, $bits, $target,
3278 $offset, @{$opts{channels}});
3279 unless (defined $count) {
3280 $self->_set_error(Imager->_error_as_msg);
3287 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3292 if ($opts{type} eq '8bit') {
3293 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3294 $opts{y}, @{$opts{channels}});
3296 elsif ($opts{type} eq 'float') {
3297 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3298 $opts{y}, @{$opts{channels}});
3300 elsif ($opts{type} =~ /^(\d+)bit$/) {
3304 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3305 $opts{y}, $bits, \@data, 0, @{$opts{channels}})
3310 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3318 my %opts = ( x => 0, offset => 0, @_ );
3320 unless ($self->{IMG}) {
3321 $self->_set_error('setsamples: empty input image');
3325 unless(defined $opts{data} && ref $opts{data}) {
3326 $self->_set_error('setsamples: data parameter missing or invalid');
3330 unless ($opts{channels}) {
3331 $opts{channels} = [ 0 .. $self->getchannels()-1 ];
3334 unless ($opts{type} && $opts{type} =~ /^(\d+)bit$/) {
3335 $self->_set_error('setsamples: type parameter missing or invalid');
3340 unless (defined $opts{width}) {
3341 $opts{width} = $self->getwidth() - $opts{x};
3344 my $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3345 $opts{channels}, $opts{data}, $opts{offset},
3347 unless (defined $count) {
3348 $self->_set_error(Imager->_error_as_msg);
3355 # make an identity matrix of the given size
3359 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3360 for my $c (0 .. ($size-1)) {
3361 $matrix->[$c][$c] = 1;
3366 # general function to convert an image
3368 my ($self, %opts) = @_;
3371 unless (defined wantarray) {
3372 my @caller = caller;
3373 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3377 # the user can either specify a matrix or preset
3378 # the matrix overrides the preset
3379 if (!exists($opts{matrix})) {
3380 unless (exists($opts{preset})) {
3381 $self->{ERRSTR} = "convert() needs a matrix or preset";
3385 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3386 # convert to greyscale, keeping the alpha channel if any
3387 if ($self->getchannels == 3) {
3388 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3390 elsif ($self->getchannels == 4) {
3391 # preserve the alpha channel
3392 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3397 $matrix = _identity($self->getchannels);
3400 elsif ($opts{preset} eq 'noalpha') {
3401 # strip the alpha channel
3402 if ($self->getchannels == 2 or $self->getchannels == 4) {
3403 $matrix = _identity($self->getchannels);
3404 pop(@$matrix); # lose the alpha entry
3407 $matrix = _identity($self->getchannels);
3410 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3412 $matrix = [ [ 1 ] ];
3414 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3415 $matrix = [ [ 0, 1 ] ];
3417 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3418 $matrix = [ [ 0, 0, 1 ] ];
3420 elsif ($opts{preset} eq 'alpha') {
3421 if ($self->getchannels == 2 or $self->getchannels == 4) {
3422 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3425 # the alpha is just 1 <shrug>
3426 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3429 elsif ($opts{preset} eq 'rgb') {
3430 if ($self->getchannels == 1) {
3431 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3433 elsif ($self->getchannels == 2) {
3434 # preserve the alpha channel
3435 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3438 $matrix = _identity($self->getchannels);
3441 elsif ($opts{preset} eq 'addalpha') {
3442 if ($self->getchannels == 1) {
3443 $matrix = _identity(2);
3445 elsif ($self->getchannels == 3) {
3446 $matrix = _identity(4);
3449 $matrix = _identity($self->getchannels);
3453 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3459 $matrix = $opts{matrix};
3462 my $new = Imager->new;
3463 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3464 unless ($new->{IMG}) {
3465 # most likely a bad matrix
3466 $self->{ERRSTR} = _error_as_msg();
3472 # combine channels from multiple input images, a class method
3474 my ($class, %opts) = @_;
3476 my $src = delete $opts{src};
3478 $class->_set_error("src parameter missing");
3483 for my $img (@$src) {
3484 unless (eval { $img->isa("Imager") }) {
3485 $class->_set_error("src must contain image objects");
3488 unless ($img->{IMG}) {
3489 $class->_set_error("empty input image");
3492 push @imgs, $img->{IMG};
3495 if (my $channels = delete $opts{channels}) {
3496 $result = i_combine(\@imgs, $channels);
3499 $result = i_combine(\@imgs);
3502 $class->_set_error($class->_error_as_msg);
3506 my $img = $class->new;
3507 $img->{IMG} = $result;
3513 # general function to map an image through lookup tables
3516 my ($self, %opts) = @_;
3517 my @chlist = qw( red green blue alpha );
3519 if (!exists($opts{'maps'})) {
3520 # make maps from channel maps
3522 for $chnum (0..$#chlist) {
3523 if (exists $opts{$chlist[$chnum]}) {
3524 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3525 } elsif (exists $opts{'all'}) {
3526 $opts{'maps'}[$chnum] = $opts{'all'};
3530 if ($opts{'maps'} and $self->{IMG}) {
3531 i_map($self->{IMG}, $opts{'maps'} );
3537 my ($self, %opts) = @_;
3539 defined $opts{mindist} or $opts{mindist} = 0;
3541 defined $opts{other}
3542 or return $self->_set_error("No 'other' parameter supplied");
3543 defined $opts{other}{IMG}
3544 or return $self->_set_error("No image data in 'other' image");
3547 or return $self->_set_error("No image data");
3549 my $result = Imager->new;
3550 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3552 or return $self->_set_error($self->_error_as_msg());
3557 # destructive border - image is shrunk by one pixel all around
3560 my ($self,%opts)=@_;
3561 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3562 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3566 # Get the width of an image
3571 if (my $raw = $self->{IMG}) {
3572 return i_img_get_width($raw);
3575 $self->{ERRSTR} = 'image is empty'; return undef;
3579 # Get the height of an image
3584 if (my $raw = $self->{IMG}) {
3585 return i_img_get_height($raw);
3588 $self->{ERRSTR} = 'image is empty'; return undef;
3592 # Get number of channels in an image
3596 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3597 return i_img_getchannels($self->{IMG});
3604 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3605 return i_img_getmask($self->{IMG});
3613 if (!defined($self->{IMG})) {
3614 $self->{ERRSTR} = 'image is empty';
3617 unless (defined $opts{mask}) {
3618 $self->_set_error("mask parameter required");
3621 i_img_setmask( $self->{IMG} , $opts{mask} );
3626 # Get number of colors in an image
3630 my %opts=('maxcolors'=>2**30,@_);
3631 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
3632 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
3633 return ($rc==-1? undef : $rc);
3636 # Returns a reference to a hash. The keys are colour named (packed) and the
3637 # values are the number of pixels in this colour.
3638 sub getcolorusagehash {
3641 my %opts = ( maxcolors => 2**30, @_ );
3642 my $max_colors = $opts{maxcolors};
3643 unless (defined $max_colors && $max_colors > 0) {
3644 $self->_set_error('maxcolors must be a positive integer');
3648 unless (defined $self->{IMG}) {
3649 $self->_set_error('empty input image');
3653 my $channels= $self->getchannels;
3654 # We don't want to look at the alpha channel, because some gifs using it
3655 # doesn't define it for every colour (but only for some)
3656 $channels -= 1 if $channels == 2 or $channels == 4;
3658 my $height = $self->getheight;
3659 for my $y (0 .. $height - 1) {
3660 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
3661 while (length $colors) {
3662 $color_use{ substr($colors, 0, $channels, '') }++;
3664 keys %color_use > $max_colors
3670 # This will return a ordered array of the colour usage. Kind of the sorted
3671 # version of the values of the hash returned by getcolorusagehash.
3672 # You might want to add safety checks and change the names, etc...
3676 my %opts = ( maxcolors => 2**30, @_ );
3677 my $max_colors = $opts{maxcolors};
3678 unless (defined $max_colors && $max_colors > 0) {
3679 $self->_set_error('maxcolors must be a positive integer');
3683 unless (defined $self->{IMG}) {
3684 $self->_set_error('empty input image');
3688 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
3691 # draw string to an image
3695 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3697 my %input=('x'=>0, 'y'=>0, @_);
3698 defined($input{string}) or $input{string} = $input{text};
3700 unless(defined $input{string}) {
3701 $self->{ERRSTR}="missing required parameter 'string'";
3705 unless($input{font}) {
3706 $self->{ERRSTR}="missing required parameter 'font'";
3710 unless ($input{font}->draw(image=>$self, %input)) {
3722 unless ($self->{IMG}) {
3723 $self->{ERRSTR}='empty input image';
3732 my %input=('x'=>0, 'y'=>0, @_);
3733 defined $input{string}
3734 or $input{string} = $input{text};
3736 unless(exists $input{string}) {
3737 $self->_set_error("missing required parameter 'string'");
3741 unless($input{font}) {
3742 $self->_set_error("missing required parameter 'font'");
3747 unless (@result = $input{font}->align(image=>$img, %input)) {
3751 return wantarray ? @result : $result[0];
3754 my @file_limit_names = qw/width height bytes/;
3756 sub set_file_limits {
3763 @values{@file_limit_names} = (0) x @file_limit_names;
3766 @values{@file_limit_names} = i_get_image_file_limits();
3769 for my $key (keys %values) {
3770 defined $opts{$key} and $values{$key} = $opts{$key};
3773 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
3776 sub get_file_limits {
3777 i_get_image_file_limits();
3780 # Shortcuts that can be exported
3782 sub newcolor { Imager::Color->new(@_); }
3783 sub newfont { Imager::Font->new(@_); }
3785 require Imager::Color::Float;
3786 return Imager::Color::Float->new(@_);
3789 *NC=*newcolour=*newcolor;
3796 #### Utility routines
3799 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
3803 my ($self, $msg) = @_;
3806 $self->{ERRSTR} = $msg;
3814 # Default guess for the type of an image from extension
3816 sub def_guess_type {
3819 $ext=($name =~ m/\.([^\.]+)$/)[0];
3820 return 'tiff' if ($ext =~ m/^tiff?$/);
3821 return 'jpeg' if ($ext =~ m/^jpe?g$/);
3822 return 'pnm' if ($ext =~ m/^p[pgb]m$/);
3823 return 'png' if ($ext eq "png");
3824 return 'bmp' if ($ext eq "bmp" || $ext eq "dib");
3825 return 'tga' if ($ext eq "tga");
3826 return 'sgi' if ($ext eq "rgb" || $ext eq "bw" || $ext eq "sgi" || $ext eq "rgba");
3827 return 'gif' if ($ext eq "gif");
3828 return 'raw' if ($ext eq "raw");
3829 return lc $ext; # best guess
3834 return @combine_types;
3837 # get the minimum of a list
3841 for(@_) { if ($_<$mx) { $mx=$_; }}
3845 # get the maximum of a list
3849 for(@_) { if ($_>$mx) { $mx=$_; }}
3853 # string stuff for iptc headers
3857 $str = substr($str,3);
3858 $str =~ s/[\n\r]//g;
3865 # A little hack to parse iptc headers.
3870 my($caption,$photogr,$headln,$credit);
3872 my $str=$self->{IPTCRAW};
3877 @ar=split(/8BIM/,$str);
3882 @sar=split(/\034\002/);
3883 foreach $item (@sar) {
3884 if ($item =~ m/^x/) {
3885 $caption = _clean($item);
3888 if ($item =~ m/^P/) {
3889 $photogr = _clean($item);
3892 if ($item =~ m/^i/) {
3893 $headln = _clean($item);
3896 if ($item =~ m/^n/) {
3897 $credit = _clean($item);
3903 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
3910 or die "Only C language supported";
3912 require Imager::ExtUtils;
3913 return Imager::ExtUtils->inline_config;
3916 # threads shouldn't try to close raw Imager objects
3917 sub Imager::ImgRaw::CLONE_SKIP { 1 }
3920 # this serves two purposes:
3921 # - a class method to load the file support modules included with Image
3922 # (or were included, once the library dependent modules are split out)
3923 # - something for Module::ScanDeps to analyze
3924 # https://rt.cpan.org/Ticket/Display.html?id=6566
3926 eval { require Imager::File::GIF };
3927 eval { require Imager::File::JPEG };
3928 eval { require Imager::File::PNG };
3929 eval { require Imager::File::SGI };
3930 eval { require Imager::File::TIFF };
3931 eval { require Imager::File::ICO };
3932 eval { require Imager::Font::W32 };
3933 eval { require Imager::Font::FT2 };
3934 eval { require Imager::Font::T1 };
3937 # backward compatibility for %formats
3938 package Imager::FORMATS;
3940 use constant IX_FORMATS => 0;
3941 use constant IX_LIST => 1;
3942 use constant IX_INDEX => 2;
3943 use constant IX_CLASSES => 3;
3946 my ($class, $formats, $classes) = @_;
3948 return bless [ $formats, [ ], 0, $classes ], $class;
3952 my ($self, $key) = @_;
3954 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
3956 if (eval { require $file; 1 }) {
3962 $self->[IX_FORMATS]{$key} = $value;
3968 my ($self, $key) = @_;
3970 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
3972 $self->[IX_CLASSES]{$key} or return undef;
3974 return $self->_check($key);
3978 die "%Imager::formats is not user monifiable";
3982 die "%Imager::formats is not user monifiable";
3986 die "%Imager::formats is not user monifiable";
3990 my ($self, $key) = @_;
3992 if (exists $self->[IX_FORMATS]{$key}) {
3993 my $value = $self->[IX_FORMATS]{$key}
3998 $self->_check($key) or return 1==0;
4006 unless (@{$self->[IX_LIST]}) {
4008 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4009 keys %{$self->[IX_FORMATS]};
4011 for my $key (keys %{$self->[IX_CLASSES]}) {
4012 $self->[IX_FORMATS]{$key} and next;
4014 and push @{$self->[IX_LIST]}, $key;
4018 @{$self->[IX_LIST]} or return;
4019 $self->[IX_INDEX] = 1;
4020 return $self->[IX_LIST][0];
4026 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4029 return $self->[IX_LIST][$self->[IX_INDEX]++];
4035 return scalar @{$self->[IX_LIST]};
4040 # Below is the stub of documentation for your module. You better edit it!
4044 Imager - Perl extension for Generating 24 bit Images
4054 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4059 # see Imager::Files for information on the read() method
4060 my $img = Imager->new(file=>$file)
4061 or die Imager->errstr();
4063 $file =~ s/\.[^.]*$//;
4065 # Create smaller version
4066 # documented in Imager::Transformations
4067 my $thumb = $img->scale(scalefactor=>.3);
4069 # Autostretch individual channels
4070 $thumb->filter(type=>'autolevels');
4072 # try to save in one of these formats
4075 for $format ( qw( png gif jpeg tiff ppm ) ) {
4076 # Check if given format is supported
4077 if ($Imager::formats{$format}) {
4078 $file.="_low.$format";
4079 print "Storing image as: $file\n";
4080 # documented in Imager::Files
4081 $thumb->write(file=>$file) or
4089 Imager is a module for creating and altering images. It can read and
4090 write various image formats, draw primitive shapes like lines,and
4091 polygons, blend multiple images together in various ways, scale, crop,
4092 render text and more.
4094 =head2 Overview of documentation
4100 Imager - This document - Synopsis, Example, Table of Contents and
4105 L<Imager::Tutorial> - a brief introduction to Imager.
4109 L<Imager::Cookbook> - how to do various things with Imager.
4113 L<Imager::ImageTypes> - Basics of constructing image objects with
4114 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4115 8/16/double bits/channel, color maps, channel masks, image tags, color
4116 quantization. Also discusses basic image information methods.
4120 L<Imager::Files> - IO interaction, reading/writing images, format
4125 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4130 L<Imager::Color> - Color specification.
4134 L<Imager::Fill> - Fill pattern specification.
4138 L<Imager::Font> - General font rendering, bounding boxes and font
4143 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4144 blending, pasting, convert and map.
4148 L<Imager::Engines> - Programmable transformations through
4149 C<transform()>, C<transform2()> and C<matrix_transform()>.
4153 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4158 L<Imager::Expr> - Expressions for evaluation engine used by
4163 L<Imager::Matrix2d> - Helper class for affine transformations.
4167 L<Imager::Fountain> - Helper for making gradient profiles.
4171 L<Imager::API> - using Imager's C API
4175 L<Imager::APIRef> - API function reference
4179 L<Imager::Inline> - using Imager's C API from Inline::C
4183 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4187 =head2 Basic Overview
4189 An Image object is created with C<$img = Imager-E<gt>new()>.
4192 $img=Imager->new(); # create empty image
4193 $img->read(file=>'lena.png',type=>'png') or # read image from file
4194 die $img->errstr(); # give an explanation
4195 # if something failed
4197 or if you want to create an empty image:
4199 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4201 This example creates a completely black image of width 400 and height
4204 =head1 ERROR HANDLING
4206 In general a method will return false when it fails, if it does use
4207 the C<errstr()> method to find out why:
4213 Returns the last error message in that context.
4215 If the last error you received was from calling an object method, such
4216 as read, call errstr() as an object method to find out why:
4218 my $image = Imager->new;
4219 $image->read(file => 'somefile.gif')
4220 or die $image->errstr;
4222 If it was a class method then call errstr() as a class method:
4224 my @imgs = Imager->read_multi(file => 'somefile.gif')
4225 or die Imager->errstr;
4227 Note that in some cases object methods are implemented in terms of
4228 class methods so a failing object method may set both.
4232 The C<Imager-E<gt>new> method is described in detail in
4233 L<Imager::ImageTypes>.
4237 Where to find information on methods for Imager class objects.
4239 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4242 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4244 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4247 arc() - L<Imager::Draw/arc()> - draw a filled arc
4249 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4252 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4254 circle() - L<Imager::Draw/circle()> - draw a filled circle
4256 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4257 colors in an image's palette (paletted images only)
4259 combine() - L<Imager::Transformations/combine()> - combine channels
4260 from one or more images.
4262 combines() - L<Imager::Draw/combines()> - return a list of the
4263 different combine type keywords
4265 compose() - L<Imager::Transformations/compose()> - compose one image
4268 convert() - L<Imager::Transformations/"Color transformations"> -
4269 transform the color space
4271 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4274 crop() - L<Imager::Transformations/crop()> - extract part of an image
4276 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4277 used to guess the output file format based on the output file name
4279 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4281 difference() - L<Imager::Filters/"Image Difference"> - produce a
4282 difference images from two input images.
4284 errstr() - L</"Basic Overview"> - the error from the last failed
4287 filter() - L<Imager::Filters> - image filtering
4289 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4290 palette, if it has one
4292 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4295 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4298 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4299 samples per pixel for an image
4301 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4302 different colors used by an image (works for direct color images)
4304 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4305 palette, if it has one
4307 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4309 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4311 get_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4313 getheight() - L<Imager::ImageTypes/getwidth()> - height of the image in
4316 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4318 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4321 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4322 row or partial row of pixels.
4324 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4325 row or partial row of pixels.
4327 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4330 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4333 init() - L<Imager::ImageTypes/init()>
4335 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4336 image write functions should write the image in their bilevel (blank
4337 and white, no gray levels) format
4339 line() - L<Imager::Draw/line()> - draw an interval
4341 load_plugin() - L<Imager::Filters/load_plugin()>
4343 map() - L<Imager::Transformations/"Color Mappings"> - remap color
4346 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4348 matrix_transform() - L<Imager::Engines/matrix_transform()>
4350 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4352 NC() - L<Imager::Handy/NC()>
4354 NCF() - L<Imager::Handy/NCF()>
4356 new() - L<Imager::ImageTypes/new()>
4358 newcolor() - L<Imager::Handy/newcolor()>
4360 newcolour() - L<Imager::Handy/newcolour()>
4362 newfont() - L<Imager::Handy/newfont()>
4364 NF() - L<Imager::Handy/NF()>
4366 open() - L<Imager::Files> - an alias for read()
4370 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4373 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4376 polygon() - L<Imager::Draw/polygon()>
4378 polyline() - L<Imager::Draw/polyline()>
4380 preload() - L<Imager::Files/preload()>
4382 read() - L<Imager::Files> - read a single image from an image file
4384 read_multi() - L<Imager::Files> - read multiple images from an image
4387 read_types() - L<Imager::Files/read_types()> - list image types Imager
4390 register_filter() - L<Imager::Filters/register_filter()>
4392 register_reader() - L<Imager::Files/register_reader()>
4394 register_writer() - L<Imager::Files/register_writer()>
4396 rotate() - L<Imager::Transformations/rotate()>
4398 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
4399 onto an image and use the alpha channel
4401 scale() - L<Imager::Transformations/scale()>
4403 scale_calculate() - L<Imager::Transformations/scale_calculate()>
4405 scaleX() - L<Imager::Transformations/scaleX()>
4407 scaleY() - L<Imager::Transformations/scaleY()>
4409 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
4412 set_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4414 setmask() - L<Imager::ImageTypes/setmask()>
4416 setpixel() - L<Imager::Draw/setpixel()>
4418 setsamples() - L<Imager::Draw/setsamples()>
4420 setscanline() - L<Imager::Draw/setscanline()>
4422 settag() - L<Imager::ImageTypes/settag()>
4424 string() - L<Imager::Draw/string()> - draw text on an image
4426 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
4428 to_paletted() - L<Imager::ImageTypes/to_paletted()>
4430 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
4432 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
4434 transform() - L<Imager::Engines/"transform()">
4436 transform2() - L<Imager::Engines/"transform2()">
4438 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
4440 unload_plugin() - L<Imager::Filters/unload_plugin()>
4442 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
4445 write() - L<Imager::Files> - write an image to a file
4447 write_multi() - L<Imager::Files> - write multiple image to an image
4450 write_types() - L<Imager::Files/read_types()> - list image types Imager
4453 =head1 CONCEPT INDEX
4455 animated GIF - L<Imager::Files/"Writing an animated GIF">
4457 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
4458 L<Imager::ImageTypes/"Common Tags">.
4460 blend - alpha blending one image onto another
4461 L<Imager::Transformations/rubthrough()>
4463 blur - L<Imager::Filters/gaussian>, L<Imager::Filters/conv>
4465 boxes, drawing - L<Imager::Draw/box()>
4467 changes between image - L<Imager::Filters/"Image Difference">
4469 channels, combine into one image - L<Imager::Transformations/combine()>
4471 color - L<Imager::Color>
4473 color names - L<Imager::Color>, L<Imager::Color::Table>
4475 combine modes - L<Imager::Draw/"Combine Types">
4477 compare images - L<Imager::Filters/"Image Difference">
4479 contrast - L<Imager::Filters/contrast>, L<Imager::Filters/autolevels>
4481 convolution - L<Imager::Filters/conv>
4483 cropping - L<Imager::Transformations/crop()>
4485 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4487 C<diff> images - L<Imager::Filters/"Image Difference">
4489 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
4490 L<Imager::Cookbook/"Image spatial resolution">
4492 drawing boxes - L<Imager::Draw/box()>
4494 drawing lines - L<Imager::Draw/line()>
4496 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
4498 error message - L</"ERROR HANDLING">
4500 files, font - L<Imager::Font>
4502 files, image - L<Imager::Files>
4504 filling, types of fill - L<Imager::Fill>
4506 filling, boxes - L<Imager::Draw/box()>
4508 filling, flood fill - L<Imager::Draw/flood_fill()>
4510 flood fill - L<Imager::Draw/flood_fill()>
4512 fonts - L<Imager::Font>
4514 fonts, drawing with - L<Imager::Draw/string()>,
4515 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
4517 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4519 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
4521 fountain fill - L<Imager::Fill/"Fountain fills">,
4522 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4523 L<Imager::Filters/gradgen>
4525 GIF files - L<Imager::Files/"GIF">
4527 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
4529 gradient fill - L<Imager::Fill/"Fountain fills">,
4530 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4531 L<Imager::Filters/gradgen>
4533 gray scale, convert image to - L<Imager::Transformations/convert()>
4535 gaussian blur - L<Imager::Filters/gaussian>
4537 hatch fills - L<Imager::Fill/"Hatched fills">
4539 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4541 invert image - L<Imager::Filters/hardinvert>,
4542 L<Imager::Filters/hardinvertall>
4544 JPEG - L<Imager::Files/"JPEG">
4546 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
4548 lines, drawing - L<Imager::Draw/line()>
4550 matrix - L<Imager::Matrix2d>,
4551 L<Imager::Engines/"Matrix Transformations">,
4552 L<Imager::Font/transform()>
4554 metadata, image - L<Imager::ImageTypes/"Tags">
4556 mosaic - L<Imager::Filters/mosaic>
4558 noise, filter - L<Imager::Filters/noise>
4560 noise, rendered - L<Imager::Filters/turbnoise>,
4561 L<Imager::Filters/radnoise>
4563 paste - L<Imager::Transformations/paste()>,
4564 L<Imager::Transformations/rubthrough()>
4566 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
4567 L<Imager::ImageTypes/new()>
4569 =for stopwords posterize
4571 posterize - L<Imager::Filters/postlevels>
4573 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
4575 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
4577 rectangles, drawing - L<Imager::Draw/box()>
4579 resizing an image - L<Imager::Transformations/scale()>,
4580 L<Imager::Transformations/crop()>
4582 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
4584 saving an image - L<Imager::Files>
4586 scaling - L<Imager::Transformations/scale()>
4588 SGI files - L<Imager::Files/"SGI (RGB, BW)">
4590 sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
4592 size, image - L<Imager::ImageTypes/getwidth()>,
4593 L<Imager::ImageTypes/getheight()>
4595 size, text - L<Imager::Font/bounding_box()>
4597 tags, image metadata - L<Imager::ImageTypes/"Tags">
4599 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
4600 L<Imager::Font::Wrap>
4602 text, wrapping text in an area - L<Imager::Font::Wrap>
4604 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4606 tiles, color - L<Imager::Filters/mosaic>
4608 transparent images - L<Imager::ImageTypes>,
4609 L<Imager::Cookbook/"Transparent PNG">
4611 =for stopwords unsharp
4613 unsharp mask - L<Imager::Filters/unsharpmask>
4615 watermark - L<Imager::Filters/watermark>
4617 writing an image to a file - L<Imager::Files>
4621 Imager doesn't support perl threads.
4623 Imager has limited code to prevent double frees if you create images,
4624 colors etc, and then create a thread, but has no code to prevent two
4625 threads entering Imager's error handling code, and none is likely to
4630 The best place to get help with Imager is the mailing list.
4632 To subscribe send a message with C<subscribe> in the body to:
4634 imager-devel+request@molar.is
4640 L<http://www.molar.is/en/lists/imager-devel/>
4644 where you can also find the mailing list archive.
4646 You can report bugs by pointing your browser at:
4650 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
4654 or by sending an email to:
4658 bug-Imager@rt.cpan.org
4662 Please remember to include the versions of Imager, perl, supporting
4663 libraries, and any relevant code. If you have specific images that
4664 cause the problems, please include those too.
4666 If you don't want to publish your email address on a mailing list you
4667 can use CPAN::Forum:
4669 http://www.cpanforum.com/dist/Imager
4671 You will need to register to post.
4673 =head1 CONTRIBUTING TO IMAGER
4679 If you like or dislike Imager, you can add a public review of Imager
4682 http://cpanratings.perl.org/dist/Imager
4684 =for stopwords Bitcard
4686 This requires a Bitcard account (http://www.bitcard.org).
4688 You can also send email to the maintainer below.
4690 If you send me a bug report via email, it will be copied to Request
4695 I accept patches, preferably against the main branch in subversion.
4696 You should include an explanation of the reason for why the patch is
4699 Your patch should include regression tests where possible, otherwise
4700 it will be delayed until I get a chance to write them.
4704 Tony Cook <tony@imager.perl.org> is the current maintainer for Imager.
4706 Arnar M. Hrafnkelsson is the original author of Imager.
4708 Many others have contributed to Imager, please see the C<README> for a
4713 Imager is licensed under the same terms as perl itself.
4716 makeblendedfont Fontforge
4718 A test font, FT2/fontfiles/MMOne.pfb, contains a Postscript operator
4719 definition copyrighted by Adobe. See F<adobe.txt> in the source for
4720 license information.
4724 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
4725 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
4726 L<Imager::Font>(3), L<Imager::Transformations>(3),
4727 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
4728 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
4730 L<http://imager.perl.org/>
4732 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
4734 Other perl imaging modules include:
4736 L<GD>(3), L<Image::Magick>(3), L<Graphics::Magick>(3).