4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR %OPCODES $I2P $FORMATGUESS $warn_obsolete);
113 # registered file readers
116 # registered file writers
119 # modules we attempted to autoload
120 my %attempted_to_load;
122 # errors from loading files
123 my %file_load_errors;
125 # what happened when we tried to load
126 my %reader_load_errors;
127 my %writer_load_errors;
129 # library keys that are image file formats
130 my %file_formats = map { $_ => 1 } qw/tiff pnm gif png jpeg raw bmp tga/;
132 # image pixel combine types
134 qw/none normal multiply dissolve add subtract diff lighten darken
135 hue saturation value color/;
137 @combine_types{@combine_types} = 0 .. $#combine_types;
138 $combine_types{mult} = $combine_types{multiply};
139 $combine_types{'sub'} = $combine_types{subtract};
140 $combine_types{sat} = $combine_types{saturation};
142 # this will be used to store global defaults at some point
147 my $ex_version = eval $Exporter::VERSION;
148 if ($ex_version < 5.57) {
154 XSLoader::load(Imager => $VERSION);
158 push @ISA, 'DynaLoader';
159 bootstrap Imager $VERSION;
166 png => "Imager::File::PNG",
167 gif => "Imager::File::GIF",
168 tiff => "Imager::File::TIFF",
169 jpeg => "Imager::File::JPEG",
170 w32 => "Imager::Font::W32",
171 ft2 => "Imager::Font::FT2",
172 t1 => "Imager::Font::T1",
175 tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
178 for(i_list_formats()) { $formats_low{$_}++; }
180 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
184 # the members of the subhashes under %filters are:
185 # callseq - a list of the parameters to the underlying filter in the
186 # order they are passed
187 # callsub - a code ref that takes a named parameter list and calls the
189 # defaults - a hash of default values
190 # names - defines names for value of given parameters so if the names
191 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
192 # foo parameter, the filter will receive 1 for the foo
195 callseq => ['image','intensity'],
196 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
200 callseq => ['image', 'amount', 'subtype'],
201 defaults => { amount=>3,subtype=>0 },
202 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
205 $filters{hardinvert} ={
206 callseq => ['image'],
208 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
211 $filters{hardinvertall} =
213 callseq => ['image'],
215 callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
218 $filters{autolevels} ={
219 callseq => ['image','lsat','usat','skew'],
220 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
221 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
224 $filters{turbnoise} ={
225 callseq => ['image'],
226 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
227 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
230 $filters{radnoise} ={
231 callseq => ['image'],
232 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
233 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
238 callseq => ['image', 'coef'],
243 i_conv($hsh{image},$hsh{coef})
244 or die Imager->_error_as_msg() . "\n";
250 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
251 defaults => { dist => 0 },
255 my @colors = @{$hsh{colors}};
258 i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
262 $filters{nearest_color} =
264 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
269 # make sure the segments are specified with colors
271 for my $color (@{$hsh{colors}}) {
272 my $new_color = _color($color)
273 or die $Imager::ERRSTR."\n";
274 push @colors, $new_color;
277 i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors,
279 or die Imager->_error_as_msg() . "\n";
282 $filters{gaussian} = {
283 callseq => [ 'image', 'stddev' ],
285 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
289 callseq => [ qw(image size) ],
290 defaults => { size => 20 },
291 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
295 callseq => [ qw(image bump elevation lightx lighty st) ],
296 defaults => { elevation=>0, st=> 2 },
299 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
300 $hsh{lightx}, $hsh{lighty}, $hsh{st});
303 $filters{bumpmap_complex} =
305 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
322 for my $cname (qw/Ia Il Is/) {
323 my $old = $hsh{$cname};
324 my $new_color = _color($old)
325 or die $Imager::ERRSTR, "\n";
326 $hsh{$cname} = $new_color;
328 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
329 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
330 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
334 $filters{postlevels} =
336 callseq => [ qw(image levels) ],
337 defaults => { levels => 10 },
338 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
340 $filters{watermark} =
342 callseq => [ qw(image wmark tx ty pixdiff) ],
343 defaults => { pixdiff=>10, tx=>0, ty=>0 },
347 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
353 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
355 ftype => { linear => 0,
361 repeat => { none => 0,
376 multiply => 2, mult => 2,
379 subtract => 5, 'sub' => 5,
389 defaults => { ftype => 0, repeat => 0, combine => 0,
390 super_sample => 0, ssample_param => 4,
403 # make sure the segments are specified with colors
405 for my $segment (@{$hsh{segments}}) {
406 my @new_segment = @$segment;
408 $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
409 push @segments, \@new_segment;
412 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
413 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
414 $hsh{ssample_param}, \@segments)
415 or die Imager->_error_as_msg() . "\n";
418 $filters{unsharpmask} =
420 callseq => [ qw(image stddev scale) ],
421 defaults => { stddev=>2.0, scale=>1.0 },
425 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
429 $FORMATGUESS=\&def_guess_type;
439 # NOTE: this might be moved to an import override later on
444 if ($_[$i] eq '-log-stderr') {
452 goto &Exporter::import;
456 Imager->open_log(log => $_[0], level => $_[1]);
461 my %parms=(loglevel=>1,@_);
463 if (exists $parms{'warn_obsolete'}) {
464 $warn_obsolete = $parms{'warn_obsolete'};
468 Imager->open_log(log => $parms{log}, level => $parms{loglevel})
472 if (exists $parms{'t1log'}) {
474 if (Imager::Font::T1::i_init_t1($parms{'t1log'})) {
475 Imager->_set_error(Imager->_error_as_msg);
489 my (%opts) = ( loglevel => 1, @_ );
491 $is_logging = i_init_log($opts{log}, $opts{loglevel});
492 unless ($is_logging) {
493 Imager->_set_error(Imager->_error_as_msg());
497 Imager->log("Imager $VERSION starting\n", 1);
503 i_init_log(undef, -1);
508 my ($class, $message, $level) = @_;
510 defined $level or $level = 1;
512 i_log_entry($message, $level);
522 print "shutdown code\n";
523 # for(keys %instances) { $instances{$_}->DESTROY(); }
524 malloc_state(); # how do decide if this should be used? -- store something from the import
525 print "Imager exiting\n";
529 # Load a filter plugin
534 my ($DSO_handle,$str)=DSO_open($filename);
535 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
536 my %funcs=DSO_funclist($DSO_handle);
537 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
539 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
541 $DSOs{$filename}=[$DSO_handle,\%funcs];
544 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
545 $DEBUG && print "eval string:\n",$evstr,"\n";
557 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
558 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
559 for(keys %{$funcref}) {
561 $DEBUG && print "unloading: $_\n";
563 my $rc=DSO_close($DSO_handle);
564 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
568 # take the results of i_error() and make a message out of it
570 return join(": ", map $_->[0], i_errors());
573 # this function tries to DWIM for color parameters
574 # color objects are used as is
575 # simple scalars are simply treated as single parameters to Imager::Color->new
576 # hashrefs are treated as named argument lists to Imager::Color->new
577 # arrayrefs are treated as list arguments to Imager::Color->new iff any
579 # other arrayrefs are treated as list arguments to Imager::Color::Float
583 # perl 5.6.0 seems to do weird things to $arg if we don't make an
584 # explicitly stringified copy
585 # I vaguely remember a bug on this on p5p, but couldn't find it
586 # through bugs.perl.org (I had trouble getting it to find any bugs)
587 my $copy = $arg . "";
591 if (UNIVERSAL::isa($arg, "Imager::Color")
592 || UNIVERSAL::isa($arg, "Imager::Color::Float")) {
596 if ($copy =~ /^HASH\(/) {
597 $result = Imager::Color->new(%$arg);
599 elsif ($copy =~ /^ARRAY\(/) {
600 $result = Imager::Color->new(@$arg);
603 $Imager::ERRSTR = "Not a color";
608 # assume Imager::Color::new knows how to handle it
609 $result = Imager::Color->new($arg);
616 my ($self, $combine, $default) = @_;
618 if (!defined $combine && ref $self) {
619 $combine = $self->{combine};
621 defined $combine or $combine = $defaults{combine};
622 defined $combine or $combine = $default;
624 if (exists $combine_types{$combine}) {
625 $combine = $combine_types{$combine};
634 $self->{IMG} and return 1;
636 $self->_set_error('empty input image');
641 # returns first defined parameter
644 return $_ if defined $_;
650 # Methods to be called on objects.
653 # Create a new Imager object takes very few parameters.
654 # usually you call this method and then call open from
655 # the resulting object
662 $self->{IMG}=undef; # Just to indicate what exists
663 $self->{ERRSTR}=undef; #
664 $self->{DEBUG}=$DEBUG;
665 $self->{DEBUG} and print "Initialized Imager\n";
666 if (defined $hsh{xsize} || defined $hsh{ysize}) {
667 unless ($self->img_set(%hsh)) {
668 $Imager::ERRSTR = $self->{ERRSTR};
672 elsif (defined $hsh{file} ||
675 defined $hsh{callback} ||
676 defined $hsh{readcb} ||
677 defined $hsh{data}) {
678 # allow $img = Imager->new(file => $filename)
681 # type is already used as a parameter to new(), rename it for the
683 if ($hsh{filetype}) {
684 $extras{type} = $hsh{filetype};
686 unless ($self->read(%hsh, %extras)) {
687 $Imager::ERRSTR = $self->{ERRSTR};
695 # Copy an entire image with no changes
696 # - if an image has magic the copy of it will not be magical
700 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
702 unless (defined wantarray) {
704 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
708 my $newcopy=Imager->new();
709 $newcopy->{IMG} = i_copy($self->{IMG});
718 unless ($self->{IMG}) {
719 $self->_set_error('empty input image');
722 my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
723 my $src = $input{img} || $input{src};
725 $self->_set_error("no source image");
728 $input{left}=0 if $input{left} <= 0;
729 $input{top}=0 if $input{top} <= 0;
731 my($r,$b)=i_img_info($src->{IMG});
732 my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
733 my ($src_right, $src_bottom);
734 if ($input{src_coords}) {
735 ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
738 if (defined $input{src_maxx}) {
739 $src_right = $input{src_maxx};
741 elsif (defined $input{width}) {
742 if ($input{width} <= 0) {
743 $self->_set_error("paste: width must me positive");
746 $src_right = $src_left + $input{width};
751 if (defined $input{src_maxy}) {
752 $src_bottom = $input{src_maxy};
754 elsif (defined $input{height}) {
755 if ($input{height} < 0) {
756 $self->_set_error("paste: height must be positive");
759 $src_bottom = $src_top + $input{height};
766 $src_right > $r and $src_right = $r;
767 $src_bottom > $b and $src_bottom = $b;
769 if ($src_right <= $src_left
770 || $src_bottom < $src_top) {
771 $self->_set_error("nothing to paste");
775 i_copyto($self->{IMG}, $src->{IMG},
776 $src_left, $src_top, $src_right, $src_bottom,
777 $input{left}, $input{top});
779 return $self; # What should go here??
782 # Crop an image - i.e. return a new image that is smaller
786 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
788 unless (defined wantarray) {
790 warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
796 my ($w, $h, $l, $r, $b, $t) =
797 @hsh{qw(width height left right bottom top)};
799 # work through the various possibilities
804 elsif (!defined $r) {
805 $r = $self->getwidth;
817 $l = int(0.5+($self->getwidth()-$w)/2);
822 $r = $self->getwidth;
828 elsif (!defined $b) {
829 $b = $self->getheight;
841 $t=int(0.5+($self->getheight()-$h)/2);
846 $b = $self->getheight;
849 ($l,$r)=($r,$l) if $l>$r;
850 ($t,$b)=($b,$t) if $t>$b;
853 $r > $self->getwidth and $r = $self->getwidth;
855 $b > $self->getheight and $b = $self->getheight;
857 if ($l == $r || $t == $b) {
858 $self->_set_error("resulting image would have no content");
861 if( $r < $l or $b < $t ) {
862 $self->_set_error("attempting to crop outside of the image");
865 my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
867 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
872 my ($self, %opts) = @_;
874 $self->{IMG} or return $self->_set_error("Not a valid image");
876 my $x = $opts{xsize} || $self->getwidth;
877 my $y = $opts{ysize} || $self->getheight;
878 my $channels = $opts{channels} || $self->getchannels;
880 my $out = Imager->new;
881 if ($channels == $self->getchannels) {
882 $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
885 $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
887 unless ($out->{IMG}) {
888 $self->{ERRSTR} = $self->_error_as_msg;
895 # Sets an image to a certain size and channel number
896 # if there was previously data in the image it is discarded
901 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
903 if (defined($self->{IMG})) {
904 # let IIM_DESTROY destroy it, it's possible this image is
905 # referenced from a virtual image (like masked)
906 #i_img_destroy($self->{IMG});
910 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
911 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
912 $hsh{maxcolors} || 256);
914 elsif ($hsh{bits} eq 'double') {
915 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
917 elsif ($hsh{bits} == 16) {
918 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
921 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
925 unless ($self->{IMG}) {
926 $self->{ERRSTR} = Imager->_error_as_msg();
933 # created a masked version of the current image
937 $self or return undef;
938 my %opts = (left => 0,
940 right => $self->getwidth,
941 bottom => $self->getheight,
943 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
945 my $result = Imager->new;
946 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
947 $opts{top}, $opts{right} - $opts{left},
948 $opts{bottom} - $opts{top});
949 unless ($result->{IMG}) {
950 $self->_set_error(Imager->_error_as_msg);
954 # keep references to the mask and base images so they don't
956 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
961 # convert an RGB image into a paletted image
965 if (@_ != 1 && !ref $_[0]) {
972 unless (defined wantarray) {
974 warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
981 my $result = Imager->new;
982 unless ($result->{IMG} = i_img_to_pal($self->{IMG}, $opts)) {
983 $self->_set_error(Imager->_error_as_msg);
991 my ($class, $quant, @images) = @_;
994 Imager->_set_error("make_palette: supply at least one image");
998 for my $img (@images) {
999 unless ($img->{IMG}) {
1000 Imager->_set_error("make_palette: image $index is empty");
1006 return i_img_make_palette($quant, map $_->{IMG}, @images);
1009 # convert a paletted (or any image) to an 8-bit/channel RGB image
1013 unless (defined wantarray) {
1014 my @caller = caller;
1015 warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
1022 my $result = Imager->new;
1023 unless ($result->{IMG} = i_img_to_rgb($self->{IMG})) {
1024 $self->_set_error(Imager->_error_as_msg());
1031 # convert a paletted (or any image) to a 16-bit/channel RGB image
1035 unless (defined wantarray) {
1036 my @caller = caller;
1037 warn "to_rgb16() called in void context - to_rgb16() returns the converted image at $caller[1] line $caller[2]\n";
1044 my $result = Imager->new;
1045 unless ($result->{IMG} = i_img_to_rgb16($self->{IMG})) {
1046 $self->_set_error(Imager->_error_as_msg());
1053 # convert a paletted (or any image) to an double/channel RGB image
1057 unless (defined wantarray) {
1058 my @caller = caller;
1059 warn "to_rgb16() called in void context - to_rgb_double() returns the converted image at $caller[1] line $caller[2]\n";
1066 my $result = Imager->new;
1067 unless ($result->{IMG} = i_img_to_drgb($self->{IMG})) {
1068 $self->_set_error(Imager->_error_as_msg());
1077 my %opts = (colors=>[], @_);
1079 unless ($self->{IMG}) {
1080 $self->_set_error("empty input image");
1084 my @colors = @{$opts{colors}}
1087 for my $color (@colors) {
1088 $color = _color($color);
1090 $self->_set_error($Imager::ERRSTR);
1095 return i_addcolors($self->{IMG}, @colors);
1100 my %opts = (start=>0, colors=>[], @_);
1102 unless ($self->{IMG}) {
1103 $self->_set_error("empty input image");
1107 my @colors = @{$opts{colors}}
1110 for my $color (@colors) {
1111 $color = _color($color);
1113 $self->_set_error($Imager::ERRSTR);
1118 return i_setcolors($self->{IMG}, $opts{start}, @colors);
1124 if (!exists $opts{start} && !exists $opts{count}) {
1127 $opts{count} = $self->colorcount;
1129 elsif (!exists $opts{count}) {
1132 elsif (!exists $opts{start}) {
1137 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
1141 i_colorcount($_[0]{IMG});
1145 i_maxcolors($_[0]{IMG});
1151 $opts{color} or return undef;
1153 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
1158 my $bits = $self->{IMG} && i_img_bits($self->{IMG});
1159 if ($bits && $bits == length(pack("d", 1)) * 8) {
1168 return i_img_type($self->{IMG}) ? "paletted" : "direct";
1174 $self->{IMG} and i_img_virtual($self->{IMG});
1180 $self->{IMG} or return;
1182 return i_img_is_monochrome($self->{IMG});
1186 my ($self, %opts) = @_;
1188 $self->{IMG} or return;
1190 if (defined $opts{name}) {
1194 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
1195 push @result, (i_tags_get($self->{IMG}, $found))[1];
1198 return wantarray ? @result : $result[0];
1200 elsif (defined $opts{code}) {
1204 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
1205 push @result, (i_tags_get($self->{IMG}, $found))[1];
1212 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
1215 return i_tags_count($self->{IMG});
1224 return -1 unless $self->{IMG};
1226 if (defined $opts{value}) {
1227 if ($opts{value} =~ /^\d+$/) {
1229 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
1232 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
1235 elsif (defined $opts{data}) {
1236 # force addition as a string
1237 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
1240 $self->{ERRSTR} = "No value supplied";
1244 elsif ($opts{code}) {
1245 if (defined $opts{value}) {
1246 if ($opts{value} =~ /^\d+$/) {
1248 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
1251 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
1254 elsif (defined $opts{data}) {
1255 # force addition as a string
1256 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
1259 $self->{ERRSTR} = "No value supplied";
1272 return 0 unless $self->{IMG};
1274 if (defined $opts{'index'}) {
1275 return i_tags_delete($self->{IMG}, $opts{'index'});
1277 elsif (defined $opts{name}) {
1278 return i_tags_delbyname($self->{IMG}, $opts{name});
1280 elsif (defined $opts{code}) {
1281 return i_tags_delbycode($self->{IMG}, $opts{code});
1284 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
1290 my ($self, %opts) = @_;
1293 $self->deltag(name=>$opts{name});
1294 return $self->addtag(name=>$opts{name}, value=>$opts{value});
1296 elsif (defined $opts{code}) {
1297 $self->deltag(code=>$opts{code});
1298 return $self->addtag(code=>$opts{code}, value=>$opts{value});
1306 sub _get_reader_io {
1307 my ($self, $input) = @_;
1310 return $input->{io}, undef;
1312 elsif ($input->{fd}) {
1313 return io_new_fd($input->{fd});
1315 elsif ($input->{fh}) {
1316 my $fd = fileno($input->{fh});
1317 unless (defined $fd) {
1318 $self->_set_error("Handle in fh option not opened");
1321 return io_new_fd($fd);
1323 elsif ($input->{file}) {
1324 my $file = IO::File->new($input->{file}, "r");
1326 $self->_set_error("Could not open $input->{file}: $!");
1330 return (io_new_fd(fileno($file)), $file);
1332 elsif ($input->{data}) {
1333 return io_new_buffer($input->{data});
1335 elsif ($input->{callback} || $input->{readcb}) {
1336 if (!$input->{seekcb}) {
1337 $self->_set_error("Need a seekcb parameter");
1339 if ($input->{maxbuffer}) {
1340 return io_new_cb($input->{writecb},
1341 $input->{callback} || $input->{readcb},
1342 $input->{seekcb}, $input->{closecb},
1343 $input->{maxbuffer});
1346 return io_new_cb($input->{writecb},
1347 $input->{callback} || $input->{readcb},
1348 $input->{seekcb}, $input->{closecb});
1352 $self->_set_error("file/fd/fh/data/callback parameter missing");
1357 sub _get_writer_io {
1358 my ($self, $input) = @_;
1360 my $buffered = exists $input->{buffered} ? $input->{buffered} : 1;
1367 elsif ($input->{fd}) {
1368 $io = io_new_fd($input->{fd});
1370 elsif ($input->{fh}) {
1371 my $fd = fileno($input->{fh});
1372 unless (defined $fd) {
1373 $self->_set_error("Handle in fh option not opened");
1377 my $oldfh = select($input->{fh});
1378 # flush anything that's buffered, and make sure anything else is flushed
1381 $io = io_new_fd($fd);
1383 elsif ($input->{file}) {
1384 my $fh = new IO::File($input->{file},"w+");
1386 $self->_set_error("Could not open file $input->{file}: $!");
1389 binmode($fh) or die;
1390 $io = io_new_fd(fileno($fh));
1393 elsif ($input->{data}) {
1394 $io = io_new_bufchain();
1396 elsif ($input->{callback} || $input->{writecb}) {
1397 if ($input->{maxbuffer} && $input->{maxbuffer} == 1) {
1400 $io = io_new_cb($input->{callback} || $input->{writecb},
1402 $input->{seekcb}, $input->{closecb});
1405 $self->_set_error("file/fd/fh/data/callback parameter missing");
1409 unless ($buffered) {
1410 $io->set_buffered(0);
1413 return ($io, @extras);
1416 # Read an image from file
1422 if (defined($self->{IMG})) {
1423 # let IIM_DESTROY do the destruction, since the image may be
1424 # referenced from elsewhere
1425 #i_img_destroy($self->{IMG});
1426 undef($self->{IMG});
1429 my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
1431 my $type = $input{'type'};
1433 $type = i_test_format_probe($IO, -1);
1436 if ($input{file} && !$type) {
1438 $type = $FORMATGUESS->($input{file});
1442 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1443 $input{file} and $msg .= " or file name";
1444 $self->_set_error($msg);
1448 _reader_autoload($type);
1450 if ($readers{$type} && $readers{$type}{single}) {
1451 return $readers{$type}{single}->($self, $IO, %input);
1454 unless ($formats_low{$type}) {
1455 my $read_types = join ', ', sort Imager->read_types();
1456 $self->_set_error("format '$type' not supported - formats $read_types available for reading - $reader_load_errors{$type}");
1460 my $allow_incomplete = $input{allow_incomplete};
1461 defined $allow_incomplete or $allow_incomplete = 0;
1463 if ( $type eq 'pnm' ) {
1464 $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
1465 if ( !defined($self->{IMG}) ) {
1466 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
1469 $self->{DEBUG} && print "loading a pnm file\n";
1473 if ( $type eq 'bmp' ) {
1474 $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
1475 if ( !defined($self->{IMG}) ) {
1476 $self->{ERRSTR}=$self->_error_as_msg();
1479 $self->{DEBUG} && print "loading a bmp file\n";
1482 if ( $type eq 'gif' ) {
1483 if ($input{colors} && !ref($input{colors})) {
1484 # must be a reference to a scalar that accepts the colour map
1485 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
1488 if ($input{'gif_consolidate'}) {
1489 if ($input{colors}) {
1491 ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
1493 ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
1497 $self->{IMG} =i_readgif_wiol( $IO );
1501 my $page = $input{'page'};
1502 defined $page or $page = 0;
1503 $self->{IMG} = i_readgif_single_wiol( $IO, $page );
1504 if ($self->{IMG} && $input{colors}) {
1505 ${ $input{colors} } =
1506 [ i_getcolors($self->{IMG}, 0, i_colorcount($self->{IMG})) ];
1510 if ( !defined($self->{IMG}) ) {
1511 $self->{ERRSTR}=$self->_error_as_msg();
1514 $self->{DEBUG} && print "loading a gif file\n";
1517 if ( $type eq 'tga' ) {
1518 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
1519 if ( !defined($self->{IMG}) ) {
1520 $self->{ERRSTR}=$self->_error_as_msg();
1523 $self->{DEBUG} && print "loading a tga file\n";
1526 if ( $type eq 'raw' ) {
1527 unless ( $input{xsize} && $input{ysize} ) {
1528 $self->_set_error('missing xsize or ysize parameter for raw');
1532 my $interleave = _first($input{raw_interleave}, $input{interleave});
1533 unless (defined $interleave) {
1534 my @caller = caller;
1535 warn "read(type => 'raw') $caller[2] line $caller[1]: supply interleave or raw_interleave for future compatibility\n";
1538 my $data_ch = _first($input{raw_datachannels}, $input{datachannels}, 3);
1539 my $store_ch = _first($input{raw_storechannels}, $input{storechannels}, 3);
1541 $self->{IMG} = i_readraw_wiol( $IO,
1547 if ( !defined($self->{IMG}) ) {
1548 $self->{ERRSTR}=$self->_error_as_msg();
1551 $self->{DEBUG} && print "loading a raw file\n";
1557 sub register_reader {
1558 my ($class, %opts) = @_;
1561 or die "register_reader called with no type parameter\n";
1563 my $type = $opts{type};
1565 defined $opts{single} || defined $opts{multiple}
1566 or die "register_reader called with no single or multiple parameter\n";
1568 $readers{$type} = { };
1569 if ($opts{single}) {
1570 $readers{$type}{single} = $opts{single};
1572 if ($opts{multiple}) {
1573 $readers{$type}{multiple} = $opts{multiple};
1579 sub register_writer {
1580 my ($class, %opts) = @_;
1583 or die "register_writer called with no type parameter\n";
1585 my $type = $opts{type};
1587 defined $opts{single} || defined $opts{multiple}
1588 or die "register_writer called with no single or multiple parameter\n";
1590 $writers{$type} = { };
1591 if ($opts{single}) {
1592 $writers{$type}{single} = $opts{single};
1594 if ($opts{multiple}) {
1595 $writers{$type}{multiple} = $opts{multiple};
1606 grep($file_formats{$_}, keys %formats),
1607 qw(ico sgi), # formats not handled directly, but supplied with Imager
1618 grep($file_formats{$_}, keys %formats),
1619 qw(ico sgi), # formats not handled directly, but supplied with Imager
1626 my ($file, $error) = @_;
1628 if ($attempted_to_load{$file}) {
1629 if ($file_load_errors{$file}) {
1630 $$error = $file_load_errors{$file};
1638 local $SIG{__DIE__};
1640 ++$attempted_to_load{$file};
1648 my $work = $@ || "Unknown error loading $file";
1650 $work =~ s/\n?Compilation failed in require at .*Imager\.pm line .*\z//m;
1651 $work =~ s/\n/\\n/g;
1652 $file_load_errors{$file} = $work;
1659 # probes for an Imager::File::whatever module
1660 sub _reader_autoload {
1663 return if $formats_low{$type} || $readers{$type};
1665 return unless $type =~ /^\w+$/;
1667 my $file = "Imager/File/\U$type\E.pm";
1670 my $loaded = _load_file($file, \$error);
1671 if (!$loaded && $error =~ /^Can't locate /) {
1672 my $filer = "Imager/File/\U$type\EReader.pm";
1673 $loaded = _load_file($filer, \$error);
1674 if ($error =~ /^Can't locate /) {
1675 $error = "Can't locate $file or $filer";
1679 $reader_load_errors{$type} = $error;
1683 # probes for an Imager::File::whatever module
1684 sub _writer_autoload {
1687 return if $formats_low{$type} || $writers{$type};
1689 return unless $type =~ /^\w+$/;
1691 my $file = "Imager/File/\U$type\E.pm";
1694 my $loaded = _load_file($file, \$error);
1695 if (!$loaded && $error =~ /^Can't locate /) {
1696 my $filew = "Imager/File/\U$type\EWriter.pm";
1697 $loaded = _load_file($filew, \$error);
1698 if ($error =~ /^Can't locate /) {
1699 $error = "Can't locate $file or $filew";
1703 $writer_load_errors{$type} = $error;
1707 sub _fix_gif_positions {
1708 my ($opts, $opt, $msg, @imgs) = @_;
1710 my $positions = $opts->{'gif_positions'};
1712 for my $pos (@$positions) {
1713 my ($x, $y) = @$pos;
1714 my $img = $imgs[$index++];
1715 $img->settag(name=>'gif_left', value=>$x);
1716 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1718 $$msg .= "replaced with the gif_left and gif_top tags";
1723 gif_each_palette=>'gif_local_map',
1724 interlace => 'gif_interlace',
1725 gif_delays => 'gif_delay',
1726 gif_positions => \&_fix_gif_positions,
1727 gif_loop_count => 'gif_loop',
1730 # options that should be converted to colors
1731 my %color_opts = map { $_ => 1 } qw/i_background/;
1734 my ($self, $opts, $prefix, @imgs) = @_;
1736 for my $opt (keys %$opts) {
1738 if ($obsolete_opts{$opt}) {
1739 my $new = $obsolete_opts{$opt};
1740 my $msg = "Obsolete option $opt ";
1742 $new->($opts, $opt, \$msg, @imgs);
1745 $msg .= "replaced with the $new tag ";
1748 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1749 warn $msg if $warn_obsolete && $^W;
1751 next unless $tagname =~ /^\Q$prefix/;
1752 my $value = $opts->{$opt};
1753 if ($color_opts{$opt}) {
1754 $value = _color($value);
1756 $self->_set_error($Imager::ERRSTR);
1761 if (UNIVERSAL::isa($value, "Imager::Color")) {
1762 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1763 for my $img (@imgs) {
1764 $img->settag(name=>$tagname, value=>$tag);
1767 elsif (ref($value) eq 'ARRAY') {
1768 for my $i (0..$#$value) {
1769 my $val = $value->[$i];
1771 if (UNIVERSAL::isa($val, "Imager::Color")) {
1772 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1774 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1777 $self->_set_error("Unknown reference type " . ref($value) .
1778 " supplied in array for $opt");
1784 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1789 $self->_set_error("Unknown reference type " . ref($value) .
1790 " supplied for $opt");
1795 # set it as a tag for every image
1796 for my $img (@imgs) {
1797 $img->settag(name=>$tagname, value=>$value);
1805 # Write an image to file
1808 my %input=(jpegquality=>75,
1818 $self->_set_opts(\%input, "i_", $self)
1821 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1823 my $type = $input{'type'};
1824 if (!$type and $input{file}) {
1825 $type = $FORMATGUESS->($input{file});
1828 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1832 _writer_autoload($type);
1835 if ($writers{$type} && $writers{$type}{single}) {
1836 ($IO, $fh) = $self->_get_writer_io(\%input)
1839 $writers{$type}{single}->($self, $IO, %input, type => $type)
1843 if (!$formats_low{$type}) {
1844 my $write_types = join ', ', sort Imager->write_types();
1845 $self->_set_error("format '$type' not supported - formats $write_types available for writing - $writer_load_errors{$type}");
1849 ($IO, $fh) = $self->_get_writer_io(\%input, $type)
1852 if ( $type eq 'pnm' ) {
1853 $self->_set_opts(\%input, "pnm_", $self)
1855 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1856 $self->{ERRSTR} = $self->_error_as_msg();
1859 $self->{DEBUG} && print "writing a pnm file\n";
1861 elsif ( $type eq 'raw' ) {
1862 $self->_set_opts(\%input, "raw_", $self)
1864 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1865 $self->{ERRSTR} = $self->_error_as_msg();
1868 $self->{DEBUG} && print "writing a raw file\n";
1870 elsif ( $type eq 'bmp' ) {
1871 $self->_set_opts(\%input, "bmp_", $self)
1873 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1874 $self->{ERRSTR} = $self->_error_as_msg;
1877 $self->{DEBUG} && print "writing a bmp file\n";
1879 elsif ( $type eq 'tga' ) {
1880 $self->_set_opts(\%input, "tga_", $self)
1883 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1884 $self->{ERRSTR}=$self->_error_as_msg();
1887 $self->{DEBUG} && print "writing a tga file\n";
1891 if (exists $input{'data'}) {
1892 my $data = io_slurp($IO);
1894 $self->{ERRSTR}='Could not slurp from buffer';
1897 ${$input{data}} = $data;
1903 my ($class, $opts, @images) = @_;
1905 my $type = $opts->{type};
1907 if (!$type && $opts->{'file'}) {
1908 $type = $FORMATGUESS->($opts->{'file'});
1911 $class->_set_error('type parameter missing and not possible to guess from extension');
1914 # translate to ImgRaw
1915 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1916 $class->_set_error('Usage: Imager->write_multi({ options }, @images)');
1919 $class->_set_opts($opts, "i_", @images)
1921 my @work = map $_->{IMG}, @images;
1923 _writer_autoload($type);
1926 if ($writers{$type} && $writers{$type}{multiple}) {
1927 ($IO, $file) = $class->_get_writer_io($opts, $type)
1930 $writers{$type}{multiple}->($class, $IO, $opts, @images)
1934 if (!$formats{$type}) {
1935 my $write_types = join ', ', sort Imager->write_types();
1936 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
1940 ($IO, $file) = $class->_get_writer_io($opts, $type)
1943 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
1947 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
1952 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
1958 if (exists $opts->{'data'}) {
1959 my $data = io_slurp($IO);
1961 Imager->_set_error('Could not slurp from buffer');
1964 ${$opts->{data}} = $data;
1969 # read multiple images from a file
1971 my ($class, %opts) = @_;
1973 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
1976 my $type = $opts{'type'};
1978 $type = i_test_format_probe($IO, -1);
1981 if ($opts{file} && !$type) {
1983 $type = $FORMATGUESS->($opts{file});
1987 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1988 $opts{file} and $msg .= " or file name";
1989 Imager->_set_error($msg);
1993 _reader_autoload($type);
1995 if ($readers{$type} && $readers{$type}{multiple}) {
1996 return $readers{$type}{multiple}->($IO, %opts);
1999 unless ($formats{$type}) {
2000 my $read_types = join ', ', sort Imager->read_types();
2001 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
2006 if ($type eq 'pnm') {
2007 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
2010 my $img = Imager->new;
2011 if ($img->read(%opts, io => $IO, type => $type)) {
2014 Imager->_set_error($img->errstr);
2019 $ERRSTR = _error_as_msg();
2023 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
2027 # Destroy an Imager object
2031 # delete $instances{$self};
2032 if (defined($self->{IMG})) {
2033 # the following is now handled by the XS DESTROY method for
2034 # Imager::ImgRaw object
2035 # Re-enabling this will break virtual images
2036 # tested for in t/t020masked.t
2037 # i_img_destroy($self->{IMG});
2038 undef($self->{IMG});
2040 # print "Destroy Called on an empty image!\n"; # why did I put this here??
2044 # Perform an inplace filter of an image
2045 # that is the image will be overwritten with the data
2051 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2053 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
2055 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
2056 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
2059 if ($filters{$input{'type'}}{names}) {
2060 my $names = $filters{$input{'type'}}{names};
2061 for my $name (keys %$names) {
2062 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
2063 $input{$name} = $names->{$name}{$input{$name}};
2067 if (defined($filters{$input{'type'}}{defaults})) {
2068 %hsh=( image => $self->{IMG},
2070 %{$filters{$input{'type'}}{defaults}},
2073 %hsh=( image => $self->{IMG},
2078 my @cs=@{$filters{$input{'type'}}{callseq}};
2081 if (!defined($hsh{$_})) {
2082 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
2087 local $SIG{__DIE__}; # we don't want this processed by confess, etc
2088 &{$filters{$input{'type'}}{callsub}}(%hsh);
2091 chomp($self->{ERRSTR} = $@);
2097 $self->{DEBUG} && print "callseq is: @cs\n";
2098 $self->{DEBUG} && print "matching callseq is: @b\n";
2103 sub register_filter {
2105 my %hsh = ( defaults => {}, @_ );
2108 or die "register_filter() with no type\n";
2109 defined $hsh{callsub}
2110 or die "register_filter() with no callsub\n";
2111 defined $hsh{callseq}
2112 or die "register_filter() with no callseq\n";
2114 exists $filters{$hsh{type}}
2117 $filters{$hsh{type}} = \%hsh;
2122 sub scale_calculate {
2125 my %opts = ('type'=>'max', @_);
2127 # none of these should be references
2128 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2129 if (defined $opts{$name} && ref $opts{$name}) {
2130 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2135 my ($x_scale, $y_scale);
2136 my $width = $opts{width};
2137 my $height = $opts{height};
2139 defined $width or $width = $self->getwidth;
2140 defined $height or $height = $self->getheight;
2143 unless (defined $width && defined $height) {
2144 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2149 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2150 $x_scale = $opts{'xscalefactor'};
2151 $y_scale = $opts{'yscalefactor'};
2153 elsif ($opts{'xscalefactor'}) {
2154 $x_scale = $opts{'xscalefactor'};
2155 $y_scale = $opts{'scalefactor'} || $x_scale;
2157 elsif ($opts{'yscalefactor'}) {
2158 $y_scale = $opts{'yscalefactor'};
2159 $x_scale = $opts{'scalefactor'} || $y_scale;
2162 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2165 # work out the scaling
2166 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2167 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2168 $opts{ypixels} / $height );
2169 if ($opts{'type'} eq 'min') {
2170 $x_scale = $y_scale = _min($xpix,$ypix);
2172 elsif ($opts{'type'} eq 'max') {
2173 $x_scale = $y_scale = _max($xpix,$ypix);
2175 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2180 $self->_set_error('invalid value for type parameter');
2183 } elsif ($opts{xpixels}) {
2184 $x_scale = $y_scale = $opts{xpixels} / $width;
2186 elsif ($opts{ypixels}) {
2187 $x_scale = $y_scale = $opts{ypixels}/$height;
2189 elsif ($opts{constrain} && ref $opts{constrain}
2190 && $opts{constrain}->can('constrain')) {
2191 # we've been passed an Image::Math::Constrain object or something
2192 # that looks like one
2194 (undef, undef, $scalefactor)
2195 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2196 unless ($scalefactor) {
2197 $self->_set_error('constrain method failed on constrain parameter');
2200 $x_scale = $y_scale = $scalefactor;
2203 my $new_width = int($x_scale * $width + 0.5);
2204 $new_width > 0 or $new_width = 1;
2205 my $new_height = int($y_scale * $height + 0.5);
2206 $new_height > 0 or $new_height = 1;
2208 return ($x_scale, $y_scale, $new_width, $new_height);
2212 # Scale an image to requested size and return the scaled version
2216 my %opts = (qtype=>'normal' ,@_);
2217 my $img = Imager->new();
2218 my $tmp = Imager->new();
2220 unless (defined wantarray) {
2221 my @caller = caller;
2222 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2226 unless ($self->{IMG}) {
2227 $self->_set_error('empty input image');
2231 my ($x_scale, $y_scale, $new_width, $new_height) =
2232 $self->scale_calculate(%opts)
2235 if ($opts{qtype} eq 'normal') {
2236 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2237 if ( !defined($tmp->{IMG}) ) {
2238 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2241 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2242 if ( !defined($img->{IMG}) ) {
2243 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2249 elsif ($opts{'qtype'} eq 'preview') {
2250 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2251 if ( !defined($img->{IMG}) ) {
2252 $self->{ERRSTR}='unable to scale image';
2257 elsif ($opts{'qtype'} eq 'mixing') {
2258 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2259 unless ($img->{IMG}) {
2260 $self->_set_error(Imager->_error_as_msg);
2266 $self->_set_error('invalid value for qtype parameter');
2271 # Scales only along the X axis
2275 my %opts = ( scalefactor=>0.5, @_ );
2277 unless (defined wantarray) {
2278 my @caller = caller;
2279 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2283 unless ($self->{IMG}) {
2284 $self->{ERRSTR} = 'empty input image';
2288 my $img = Imager->new();
2290 my $scalefactor = $opts{scalefactor};
2292 if ($opts{pixels}) {
2293 $scalefactor = $opts{pixels} / $self->getwidth();
2296 unless ($self->{IMG}) {
2297 $self->{ERRSTR}='empty input image';
2301 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2303 if ( !defined($img->{IMG}) ) {
2304 $self->{ERRSTR} = 'unable to scale image';
2311 # Scales only along the Y axis
2315 my %opts = ( scalefactor => 0.5, @_ );
2317 unless (defined wantarray) {
2318 my @caller = caller;
2319 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2323 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2325 my $img = Imager->new();
2327 my $scalefactor = $opts{scalefactor};
2329 if ($opts{pixels}) {
2330 $scalefactor = $opts{pixels} / $self->getheight();
2333 unless ($self->{IMG}) {
2334 $self->{ERRSTR} = 'empty input image';
2337 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2339 if ( !defined($img->{IMG}) ) {
2340 $self->{ERRSTR} = 'unable to scale image';
2347 # Transform returns a spatial transformation of the input image
2348 # this moves pixels to a new location in the returned image.
2349 # NOTE - should make a utility function to check transforms for
2354 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2356 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2358 # print Dumper(\%opts);
2361 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2363 eval ("use Affix::Infix2Postfix;");
2366 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2369 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2370 {op=>'-',trans=>'Sub'},
2371 {op=>'*',trans=>'Mult'},
2372 {op=>'/',trans=>'Div'},
2373 {op=>'-','type'=>'unary',trans=>'u-'},
2375 {op=>'func','type'=>'unary'}],
2376 'grouping'=>[qw( \( \) )],
2377 'func'=>[qw( sin cos )],
2382 @xt=$I2P->translate($opts{'xexpr'});
2383 @yt=$I2P->translate($opts{'yexpr'});
2385 $numre=$I2P->{'numre'};
2388 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2389 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2390 @{$opts{'parm'}}=@pt;
2393 # print Dumper(\%opts);
2395 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2396 $self->{ERRSTR}='transform: no xopcodes given.';
2400 @op=@{$opts{'xopcodes'}};
2402 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2403 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2406 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2412 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2413 $self->{ERRSTR}='transform: no yopcodes given.';
2417 @op=@{$opts{'yopcodes'}};
2419 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2420 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2423 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2428 if ( !exists $opts{'parm'}) {
2429 $self->{ERRSTR}='transform: no parameter arg given.';
2433 # print Dumper(\@ropx);
2434 # print Dumper(\@ropy);
2435 # print Dumper(\@ropy);
2437 my $img = Imager->new();
2438 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2439 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2445 my ($opts, @imgs) = @_;
2447 require "Imager/Expr.pm";
2449 $opts->{variables} = [ qw(x y) ];
2450 my ($width, $height) = @{$opts}{qw(width height)};
2452 $width ||= $imgs[0]->getwidth();
2453 $height ||= $imgs[0]->getheight();
2455 for my $img (@imgs) {
2456 $opts->{constants}{"w$img_num"} = $img->getwidth();
2457 $opts->{constants}{"h$img_num"} = $img->getheight();
2458 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2459 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2464 $opts->{constants}{w} = $width;
2465 $opts->{constants}{cx} = $width/2;
2468 $Imager::ERRSTR = "No width supplied";
2472 $opts->{constants}{h} = $height;
2473 $opts->{constants}{cy} = $height/2;
2476 $Imager::ERRSTR = "No height supplied";
2479 my $code = Imager::Expr->new($opts);
2481 $Imager::ERRSTR = Imager::Expr::error();
2484 my $channels = $opts->{channels} || 3;
2485 unless ($channels >= 1 && $channels <= 4) {
2486 return Imager->_set_error("channels must be an integer between 1 and 4");
2489 my $img = Imager->new();
2490 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2491 $channels, $code->code(),
2492 $code->nregs(), $code->cregs(),
2493 [ map { $_->{IMG} } @imgs ]);
2494 if (!defined $img->{IMG}) {
2495 $Imager::ERRSTR = Imager->_error_as_msg();
2506 unless ($self->{IMG}) {
2507 $self->{ERRSTR}='empty input image';
2510 unless ($opts{src} && $opts{src}->{IMG}) {
2511 $self->{ERRSTR}='empty input image for src';
2515 %opts = (src_minx => 0,
2517 src_maxx => $opts{src}->getwidth(),
2518 src_maxy => $opts{src}->getheight(),
2522 defined $tx or $tx = $opts{left};
2523 defined $tx or $tx = 0;
2526 defined $ty or $ty = $opts{top};
2527 defined $ty or $ty = 0;
2529 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2530 $opts{src_minx}, $opts{src_miny},
2531 $opts{src_maxx}, $opts{src_maxy})) {
2532 $self->_set_error($self->_error_as_msg());
2549 unless ($self->{IMG}) {
2550 $self->_set_error("compose: empty input image");
2554 unless ($opts{src}) {
2555 $self->_set_error("compose: src parameter missing");
2559 unless ($opts{src}{IMG}) {
2560 $self->_set_error("compose: src parameter empty image");
2563 my $src = $opts{src};
2565 my $left = $opts{left};
2566 defined $left or $left = $opts{tx};
2567 defined $left or $left = 0;
2569 my $top = $opts{top};
2570 defined $top or $top = $opts{ty};
2571 defined $top or $top = 0;
2573 my $src_left = $opts{src_left};
2574 defined $src_left or $src_left = $opts{src_minx};
2575 defined $src_left or $src_left = 0;
2577 my $src_top = $opts{src_top};
2578 defined $src_top or $src_top = $opts{src_miny};
2579 defined $src_top or $src_top = 0;
2581 my $width = $opts{width};
2582 if (!defined $width && defined $opts{src_maxx}) {
2583 $width = $opts{src_maxx} - $src_left;
2585 defined $width or $width = $src->getwidth() - $src_left;
2587 my $height = $opts{height};
2588 if (!defined $height && defined $opts{src_maxy}) {
2589 $height = $opts{src_maxy} - $src_top;
2591 defined $height or $height = $src->getheight() - $src_top;
2593 my $combine = $self->_combine($opts{combine}, 'normal');
2596 unless ($opts{mask}{IMG}) {
2597 $self->_set_error("compose: mask parameter empty image");
2601 my $mask_left = $opts{mask_left};
2602 defined $mask_left or $mask_left = $opts{mask_minx};
2603 defined $mask_left or $mask_left = 0;
2605 my $mask_top = $opts{mask_top};
2606 defined $mask_top or $mask_top = $opts{mask_miny};
2607 defined $mask_top or $mask_top = 0;
2609 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2610 $left, $top, $src_left, $src_top,
2611 $mask_left, $mask_top, $width, $height,
2612 $combine, $opts{opacity})) {
2613 $self->_set_error(Imager->_error_as_msg);
2618 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2619 $width, $height, $combine, $opts{opacity})) {
2620 $self->_set_error(Imager->_error_as_msg);
2631 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2633 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2634 $dir = $xlate{$opts{'dir'}};
2635 return $self if i_flipxy($self->{IMG}, $dir);
2643 unless (defined wantarray) {
2644 my @caller = caller;
2645 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2649 if (defined $opts{right}) {
2650 my $degrees = $opts{right};
2652 $degrees += 360 * int(((-$degrees)+360)/360);
2654 $degrees = $degrees % 360;
2655 if ($degrees == 0) {
2656 return $self->copy();
2658 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2659 my $result = Imager->new();
2660 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2664 $self->{ERRSTR} = $self->_error_as_msg();
2669 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2673 elsif (defined $opts{radians} || defined $opts{degrees}) {
2674 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
2676 my $back = $opts{back};
2677 my $result = Imager->new;
2679 $back = _color($back);
2681 $self->_set_error(Imager->errstr);
2685 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2688 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2690 if ($result->{IMG}) {
2694 $self->{ERRSTR} = $self->_error_as_msg();
2699 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2704 sub matrix_transform {
2708 unless (defined wantarray) {
2709 my @caller = caller;
2710 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2714 if ($opts{matrix}) {
2715 my $xsize = $opts{xsize} || $self->getwidth;
2716 my $ysize = $opts{ysize} || $self->getheight;
2718 my $result = Imager->new;
2720 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2721 $opts{matrix}, $opts{back})
2725 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2733 $self->{ERRSTR} = "matrix parameter required";
2739 *yatf = \&matrix_transform;
2741 # These two are supported for legacy code only
2744 return Imager::Color->new(@_);
2748 return Imager::Color::set(@_);
2751 # Draws a box between the specified corner points.
2754 my $raw = $self->{IMG};
2757 $self->{ERRSTR}='empty input image';
2763 my ($xmin, $ymin, $xmax, $ymax);
2764 if (exists $opts{'box'}) {
2765 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2766 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2767 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2768 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2771 defined($xmin = $opts{xmin}) or $xmin = 0;
2772 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2773 defined($ymin = $opts{ymin}) or $ymin = 0;
2774 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2777 if ($opts{filled}) {
2778 my $color = $opts{'color'};
2780 if (defined $color) {
2781 unless (_is_color_object($color)) {
2782 $color = _color($color);
2784 $self->{ERRSTR} = $Imager::ERRSTR;
2790 $color = i_color_new(255,255,255,255);
2793 if ($color->isa("Imager::Color")) {
2794 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2797 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2800 elsif ($opts{fill}) {
2801 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2802 # assume it's a hash ref
2803 require 'Imager/Fill.pm';
2804 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2805 $self->{ERRSTR} = $Imager::ERRSTR;
2809 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2812 my $color = $opts{'color'};
2813 if (defined $color) {
2814 unless (_is_color_object($color)) {
2815 $color = _color($color);
2817 $self->{ERRSTR} = $Imager::ERRSTR;
2823 $color = i_color_new(255, 255, 255, 255);
2826 $self->{ERRSTR} = $Imager::ERRSTR;
2829 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2837 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2838 my $dflcl= [ 255, 255, 255, 255];
2843 'r'=>_min($self->getwidth(),$self->getheight())/3,
2844 'x'=>$self->getwidth()/2,
2845 'y'=>$self->getheight()/2,
2852 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2853 # assume it's a hash ref
2854 require 'Imager/Fill.pm';
2855 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2856 $self->{ERRSTR} = $Imager::ERRSTR;
2860 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2861 $opts{'d2'}, $opts{fill}{fill});
2863 elsif ($opts{filled}) {
2864 my $color = _color($opts{'color'});
2866 $self->{ERRSTR} = $Imager::ERRSTR;
2869 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2870 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2874 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2875 $opts{'d1'}, $opts{'d2'}, $color);
2879 my $color = _color($opts{'color'});
2880 if ($opts{d2} - $opts{d1} >= 360) {
2881 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
2884 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
2890 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2891 # assume it's a hash ref
2892 require 'Imager/Fill.pm';
2893 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2894 $self->{ERRSTR} = $Imager::ERRSTR;
2898 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2899 $opts{'d2'}, $opts{fill}{fill});
2902 my $color = _color($opts{'color'});
2904 $self->{ERRSTR} = $Imager::ERRSTR;
2907 if ($opts{filled}) {
2908 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2909 $opts{'d1'}, $opts{'d2'}, $color);
2912 if ($opts{d1} == 0 && $opts{d2} == 361) {
2913 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
2916 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
2922 $self->_set_error($self->_error_as_msg);
2929 # Draws a line from one point to the other
2930 # the endpoint is set if the endp parameter is set which it is by default.
2931 # to turn of the endpoint being set use endp=>0 when calling line.
2935 my $dflcl=i_color_new(0,0,0,0);
2936 my %opts=(color=>$dflcl,
2939 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2941 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
2942 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
2944 my $color = _color($opts{'color'});
2946 $self->{ERRSTR} = $Imager::ERRSTR;
2950 $opts{antialias} = $opts{aa} if defined $opts{aa};
2951 if ($opts{antialias}) {
2952 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2953 $color, $opts{endp});
2955 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2956 $color, $opts{endp});
2961 # Draws a line between an ordered set of points - It more or less just transforms this
2962 # into a list of lines.
2966 my ($pt,$ls,@points);
2967 my $dflcl=i_color_new(0,0,0,0);
2968 my %opts=(color=>$dflcl,@_);
2970 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2972 if (exists($opts{points})) { @points=@{$opts{points}}; }
2973 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
2974 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
2977 # print Dumper(\@points);
2979 my $color = _color($opts{'color'});
2981 $self->{ERRSTR} = $Imager::ERRSTR;
2984 $opts{antialias} = $opts{aa} if defined $opts{aa};
2985 if ($opts{antialias}) {
2988 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
2995 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
3005 my ($pt,$ls,@points);
3006 my $dflcl = i_color_new(0,0,0,0);
3007 my %opts = (color=>$dflcl, @_);
3009 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3011 if (exists($opts{points})) {
3012 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
3013 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
3016 if (!exists $opts{'x'} or !exists $opts{'y'}) {
3017 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
3020 if ($opts{'fill'}) {
3021 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
3022 # assume it's a hash ref
3023 require 'Imager/Fill.pm';
3024 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
3025 $self->{ERRSTR} = $Imager::ERRSTR;
3029 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
3030 $opts{'fill'}{'fill'});
3033 my $color = _color($opts{'color'});
3035 $self->{ERRSTR} = $Imager::ERRSTR;
3038 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3045 # this the multipoint bezier curve
3046 # this is here more for testing that actual usage since
3047 # this is not a good algorithm. Usually the curve would be
3048 # broken into smaller segments and each done individually.
3052 my ($pt,$ls,@points);
3053 my $dflcl=i_color_new(0,0,0,0);
3054 my %opts=(color=>$dflcl,@_);
3056 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3058 if (exists $opts{points}) {
3059 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
3060 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
3063 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
3064 $self->{ERRSTR}='Missing or invalid points.';
3068 my $color = _color($opts{'color'});
3070 $self->{ERRSTR} = $Imager::ERRSTR;
3073 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
3079 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
3082 unless (exists $opts{'x'} && exists $opts{'y'}) {
3083 $self->{ERRSTR} = "missing seed x and y parameters";
3087 if ($opts{border}) {
3088 my $border = _color($opts{border});
3090 $self->_set_error($Imager::ERRSTR);
3094 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3095 # assume it's a hash ref
3096 require Imager::Fill;
3097 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3098 $self->{ERRSTR} = $Imager::ERRSTR;
3102 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3103 $opts{fill}{fill}, $border);
3106 my $color = _color($opts{'color'});
3108 $self->{ERRSTR} = $Imager::ERRSTR;
3111 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3118 $self->{ERRSTR} = $self->_error_as_msg();
3124 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3125 # assume it's a hash ref
3126 require 'Imager/Fill.pm';
3127 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3128 $self->{ERRSTR} = $Imager::ERRSTR;
3132 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3135 my $color = _color($opts{'color'});
3137 $self->{ERRSTR} = $Imager::ERRSTR;
3140 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3146 $self->{ERRSTR} = $self->_error_as_msg();
3153 my ($self, %opts) = @_;
3155 my $color = $opts{color};
3156 unless (defined $color) {
3157 $color = $self->{fg};
3158 defined $color or $color = NC(255, 255, 255);
3161 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3162 $color = _color($color)
3166 unless (exists $opts{'x'} && exists $opts{'y'}) {
3167 $self->{ERRSTR} = 'missing x and y parameters';
3173 if (ref $x && ref $y) {
3174 unless (@$x == @$y) {
3175 $self->{ERRSTR} = 'length of x and y mismatch';
3179 if ($color->isa('Imager::Color')) {
3180 for my $i (0..$#{$opts{'x'}}) {
3181 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3186 for my $i (0..$#{$opts{'x'}}) {
3187 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3195 if ($color->isa('Imager::Color')) {
3196 i_ppix($self->{IMG}, $x, $y, $color)
3200 i_ppixf($self->{IMG}, $x, $y, $color)
3211 my %opts = ( "type"=>'8bit', @_);
3213 unless (exists $opts{'x'} && exists $opts{'y'}) {
3214 $self->{ERRSTR} = 'missing x and y parameters';
3220 if (ref $x && ref $y) {
3221 unless (@$x == @$y) {
3222 $self->{ERRSTR} = 'length of x and y mismatch';
3226 if ($opts{"type"} eq '8bit') {
3227 for my $i (0..$#{$opts{'x'}}) {
3228 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3232 for my $i (0..$#{$opts{'x'}}) {
3233 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3236 return wantarray ? @result : \@result;
3239 if ($opts{"type"} eq '8bit') {
3240 return i_get_pixel($self->{IMG}, $x, $y);
3243 return i_gpixf($self->{IMG}, $x, $y);
3252 my %opts = ( type => '8bit', x=>0, @_);
3254 $self->_valid_image or return;
3256 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3258 unless (defined $opts{'y'}) {
3259 $self->_set_error("missing y parameter");
3263 if ($opts{type} eq '8bit') {
3264 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3267 elsif ($opts{type} eq 'float') {
3268 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3271 elsif ($opts{type} eq 'index') {
3272 unless (i_img_type($self->{IMG})) {
3273 $self->_set_error("type => index only valid on paletted images");
3276 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3280 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3287 my %opts = ( x=>0, @_);
3289 $self->_valid_image or return;
3291 unless (defined $opts{'y'}) {
3292 $self->_set_error("missing y parameter");
3297 if (ref $opts{pixels} && @{$opts{pixels}}) {
3298 # try to guess the type
3299 if ($opts{pixels}[0]->isa('Imager::Color')) {
3300 $opts{type} = '8bit';
3302 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3303 $opts{type} = 'float';
3306 $self->_set_error("missing type parameter and could not guess from pixels");
3312 $opts{type} = '8bit';
3316 if ($opts{type} eq '8bit') {
3317 if (ref $opts{pixels}) {
3318 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3321 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3324 elsif ($opts{type} eq 'float') {
3325 if (ref $opts{pixels}) {
3326 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3329 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3332 elsif ($opts{type} eq 'index') {
3333 if (ref $opts{pixels}) {
3334 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3337 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3341 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3348 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3350 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3352 unless (defined $opts{'y'}) {
3353 $self->_set_error("missing y parameter");
3357 unless ($opts{channels}) {
3358 $opts{channels} = [ 0 .. $self->getchannels()-1 ];
3361 if ($opts{target}) {
3362 my $target = $opts{target};
3363 my $offset = $opts{offset};
3364 if ($opts{type} eq '8bit') {
3365 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3366 $opts{y}, @{$opts{channels}})
3368 @{$target}{$offset .. $offset + @samples - 1} = @samples;
3369 return scalar(@samples);
3371 elsif ($opts{type} eq 'float') {
3372 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3373 $opts{y}, @{$opts{channels}});
3374 @{$target}{$offset .. $offset + @samples - 1} = @samples;
3375 return scalar(@samples);
3377 elsif ($opts{type} =~ /^(\d+)bit$/) {
3381 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3382 $opts{y}, $bits, $target,
3383 $offset, @{$opts{channels}});
3384 unless (defined $count) {
3385 $self->_set_error(Imager->_error_as_msg);
3392 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3397 if ($opts{type} eq '8bit') {
3398 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3399 $opts{y}, @{$opts{channels}});
3401 elsif ($opts{type} eq 'float') {
3402 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3403 $opts{y}, @{$opts{channels}});
3405 elsif ($opts{type} =~ /^(\d+)bit$/) {
3409 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3410 $opts{y}, $bits, \@data, 0, @{$opts{channels}})
3415 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3423 my %opts = ( x => 0, offset => 0, @_ );
3425 unless ($self->{IMG}) {
3426 $self->_set_error('setsamples: empty input image');
3430 unless(defined $opts{data} && ref $opts{data}) {
3431 $self->_set_error('setsamples: data parameter missing or invalid');
3435 unless ($opts{channels}) {
3436 $opts{channels} = [ 0 .. $self->getchannels()-1 ];
3439 unless ($opts{type} && $opts{type} =~ /^(\d+)bit$/) {
3440 $self->_set_error('setsamples: type parameter missing or invalid');
3445 unless (defined $opts{width}) {
3446 $opts{width} = $self->getwidth() - $opts{x};
3449 my $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3450 $opts{channels}, $opts{data}, $opts{offset},
3452 unless (defined $count) {
3453 $self->_set_error(Imager->_error_as_msg);
3460 # make an identity matrix of the given size
3464 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3465 for my $c (0 .. ($size-1)) {
3466 $matrix->[$c][$c] = 1;
3471 # general function to convert an image
3473 my ($self, %opts) = @_;
3476 unless (defined wantarray) {
3477 my @caller = caller;
3478 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3482 # the user can either specify a matrix or preset
3483 # the matrix overrides the preset
3484 if (!exists($opts{matrix})) {
3485 unless (exists($opts{preset})) {
3486 $self->{ERRSTR} = "convert() needs a matrix or preset";
3490 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3491 # convert to greyscale, keeping the alpha channel if any
3492 if ($self->getchannels == 3) {
3493 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3495 elsif ($self->getchannels == 4) {
3496 # preserve the alpha channel
3497 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3502 $matrix = _identity($self->getchannels);
3505 elsif ($opts{preset} eq 'noalpha') {
3506 # strip the alpha channel
3507 if ($self->getchannels == 2 or $self->getchannels == 4) {
3508 $matrix = _identity($self->getchannels);
3509 pop(@$matrix); # lose the alpha entry
3512 $matrix = _identity($self->getchannels);
3515 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3517 $matrix = [ [ 1 ] ];
3519 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3520 $matrix = [ [ 0, 1 ] ];
3522 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3523 $matrix = [ [ 0, 0, 1 ] ];
3525 elsif ($opts{preset} eq 'alpha') {
3526 if ($self->getchannels == 2 or $self->getchannels == 4) {
3527 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3530 # the alpha is just 1 <shrug>
3531 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3534 elsif ($opts{preset} eq 'rgb') {
3535 if ($self->getchannels == 1) {
3536 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3538 elsif ($self->getchannels == 2) {
3539 # preserve the alpha channel
3540 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3543 $matrix = _identity($self->getchannels);
3546 elsif ($opts{preset} eq 'addalpha') {
3547 if ($self->getchannels == 1) {
3548 $matrix = _identity(2);
3550 elsif ($self->getchannels == 3) {
3551 $matrix = _identity(4);
3554 $matrix = _identity($self->getchannels);
3558 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3564 $matrix = $opts{matrix};
3567 my $new = Imager->new;
3568 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3569 unless ($new->{IMG}) {
3570 # most likely a bad matrix
3571 $self->{ERRSTR} = _error_as_msg();
3577 # combine channels from multiple input images, a class method
3579 my ($class, %opts) = @_;
3581 my $src = delete $opts{src};
3583 $class->_set_error("src parameter missing");
3588 for my $img (@$src) {
3589 unless (eval { $img->isa("Imager") }) {
3590 $class->_set_error("src must contain image objects");
3593 unless ($img->{IMG}) {
3594 $class->_set_error("empty input image");
3597 push @imgs, $img->{IMG};
3600 if (my $channels = delete $opts{channels}) {
3601 $result = i_combine(\@imgs, $channels);
3604 $result = i_combine(\@imgs);
3607 $class->_set_error($class->_error_as_msg);
3611 my $img = $class->new;
3612 $img->{IMG} = $result;
3618 # general function to map an image through lookup tables
3621 my ($self, %opts) = @_;
3622 my @chlist = qw( red green blue alpha );
3624 if (!exists($opts{'maps'})) {
3625 # make maps from channel maps
3627 for $chnum (0..$#chlist) {
3628 if (exists $opts{$chlist[$chnum]}) {
3629 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3630 } elsif (exists $opts{'all'}) {
3631 $opts{'maps'}[$chnum] = $opts{'all'};
3635 if ($opts{'maps'} and $self->{IMG}) {
3636 i_map($self->{IMG}, $opts{'maps'} );
3642 my ($self, %opts) = @_;
3644 defined $opts{mindist} or $opts{mindist} = 0;
3646 defined $opts{other}
3647 or return $self->_set_error("No 'other' parameter supplied");
3648 defined $opts{other}{IMG}
3649 or return $self->_set_error("No image data in 'other' image");
3652 or return $self->_set_error("No image data");
3654 my $result = Imager->new;
3655 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3657 or return $self->_set_error($self->_error_as_msg());
3662 # destructive border - image is shrunk by one pixel all around
3665 my ($self,%opts)=@_;
3666 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3667 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3671 # Get the width of an image
3676 if (my $raw = $self->{IMG}) {
3677 return i_img_get_width($raw);
3680 $self->{ERRSTR} = 'image is empty'; return undef;
3684 # Get the height of an image
3689 if (my $raw = $self->{IMG}) {
3690 return i_img_get_height($raw);
3693 $self->{ERRSTR} = 'image is empty'; return undef;
3697 # Get number of channels in an image
3701 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3702 return i_img_getchannels($self->{IMG});
3709 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3710 return i_img_getmask($self->{IMG});
3718 if (!defined($self->{IMG})) {
3719 $self->{ERRSTR} = 'image is empty';
3722 unless (defined $opts{mask}) {
3723 $self->_set_error("mask parameter required");
3726 i_img_setmask( $self->{IMG} , $opts{mask} );
3731 # Get number of colors in an image
3735 my %opts=('maxcolors'=>2**30,@_);
3736 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
3737 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
3738 return ($rc==-1? undef : $rc);
3741 # Returns a reference to a hash. The keys are colour named (packed) and the
3742 # values are the number of pixels in this colour.
3743 sub getcolorusagehash {
3746 my %opts = ( maxcolors => 2**30, @_ );
3747 my $max_colors = $opts{maxcolors};
3748 unless (defined $max_colors && $max_colors > 0) {
3749 $self->_set_error('maxcolors must be a positive integer');
3753 unless (defined $self->{IMG}) {
3754 $self->_set_error('empty input image');
3758 my $channels= $self->getchannels;
3759 # We don't want to look at the alpha channel, because some gifs using it
3760 # doesn't define it for every colour (but only for some)
3761 $channels -= 1 if $channels == 2 or $channels == 4;
3763 my $height = $self->getheight;
3764 for my $y (0 .. $height - 1) {
3765 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
3766 while (length $colors) {
3767 $color_use{ substr($colors, 0, $channels, '') }++;
3769 keys %color_use > $max_colors
3775 # This will return a ordered array of the colour usage. Kind of the sorted
3776 # version of the values of the hash returned by getcolorusagehash.
3777 # You might want to add safety checks and change the names, etc...
3781 my %opts = ( maxcolors => 2**30, @_ );
3782 my $max_colors = $opts{maxcolors};
3783 unless (defined $max_colors && $max_colors > 0) {
3784 $self->_set_error('maxcolors must be a positive integer');
3788 unless (defined $self->{IMG}) {
3789 $self->_set_error('empty input image');
3793 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
3796 # draw string to an image
3800 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3802 my %input=('x'=>0, 'y'=>0, @_);
3803 defined($input{string}) or $input{string} = $input{text};
3805 unless(defined $input{string}) {
3806 $self->{ERRSTR}="missing required parameter 'string'";
3810 unless($input{font}) {
3811 $self->{ERRSTR}="missing required parameter 'font'";
3815 unless ($input{font}->draw(image=>$self, %input)) {
3827 unless ($self->{IMG}) {
3828 $self->{ERRSTR}='empty input image';
3837 my %input=('x'=>0, 'y'=>0, @_);
3838 defined $input{string}
3839 or $input{string} = $input{text};
3841 unless(exists $input{string}) {
3842 $self->_set_error("missing required parameter 'string'");
3846 unless($input{font}) {
3847 $self->_set_error("missing required parameter 'font'");
3852 unless (@result = $input{font}->align(image=>$img, %input)) {
3856 return wantarray ? @result : $result[0];
3859 my @file_limit_names = qw/width height bytes/;
3861 sub set_file_limits {
3868 @values{@file_limit_names} = (0) x @file_limit_names;
3871 @values{@file_limit_names} = i_get_image_file_limits();
3874 for my $key (keys %values) {
3875 defined $opts{$key} and $values{$key} = $opts{$key};
3878 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
3881 sub get_file_limits {
3882 i_get_image_file_limits();
3885 # Shortcuts that can be exported
3887 sub newcolor { Imager::Color->new(@_); }
3888 sub newfont { Imager::Font->new(@_); }
3890 require Imager::Color::Float;
3891 return Imager::Color::Float->new(@_);
3894 *NC=*newcolour=*newcolor;
3901 #### Utility routines
3904 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
3908 my ($self, $msg) = @_;
3911 $self->{ERRSTR} = $msg;
3919 # Default guess for the type of an image from extension
3921 my @simple_types = qw(png tga gif raw ico cur xpm mng jng ilbm pcx psd eps);
3925 ( map { $_ => $_ } @simple_types ),
3931 pnm => "pnm", # technically wrong, but historically it works in Imager
3944 sub def_guess_type {
3947 my ($ext) = $name =~ /\.([^.]+)$/
3950 my $type = $ext_types{$ext}
3957 return @combine_types;
3960 # get the minimum of a list
3964 for(@_) { if ($_<$mx) { $mx=$_; }}
3968 # get the maximum of a list
3972 for(@_) { if ($_>$mx) { $mx=$_; }}
3976 # string stuff for iptc headers
3980 $str = substr($str,3);
3981 $str =~ s/[\n\r]//g;
3988 # A little hack to parse iptc headers.
3993 my($caption,$photogr,$headln,$credit);
3995 my $str=$self->{IPTCRAW};
4000 @ar=split(/8BIM/,$str);
4005 @sar=split(/\034\002/);
4006 foreach $item (@sar) {
4007 if ($item =~ m/^x/) {
4008 $caption = _clean($item);
4011 if ($item =~ m/^P/) {
4012 $photogr = _clean($item);
4015 if ($item =~ m/^i/) {
4016 $headln = _clean($item);
4019 if ($item =~ m/^n/) {
4020 $credit = _clean($item);
4026 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
4033 or die "Only C language supported";
4035 require Imager::ExtUtils;
4036 return Imager::ExtUtils->inline_config;
4039 # threads shouldn't try to close raw Imager objects
4040 sub Imager::ImgRaw::CLONE_SKIP { 1 }
4043 # this serves two purposes:
4044 # - a class method to load the file support modules included with Imager
4045 # (or were included, once the library dependent modules are split out)
4046 # - something for Module::ScanDeps to analyze
4047 # https://rt.cpan.org/Ticket/Display.html?id=6566
4049 eval { require Imager::File::GIF };
4050 eval { require Imager::File::JPEG };
4051 eval { require Imager::File::PNG };
4052 eval { require Imager::File::SGI };
4053 eval { require Imager::File::TIFF };
4054 eval { require Imager::File::ICO };
4055 eval { require Imager::Font::W32 };
4056 eval { require Imager::Font::FT2 };
4057 eval { require Imager::Font::T1 };
4060 # backward compatibility for %formats
4061 package Imager::FORMATS;
4063 use constant IX_FORMATS => 0;
4064 use constant IX_LIST => 1;
4065 use constant IX_INDEX => 2;
4066 use constant IX_CLASSES => 3;
4069 my ($class, $formats, $classes) = @_;
4071 return bless [ $formats, [ ], 0, $classes ], $class;
4075 my ($self, $key) = @_;
4077 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
4080 my $loaded = Imager::_load_file($file, \$error);
4085 if ($error =~ /^Can't locate /) {
4086 $error = "Can't locate $file";
4088 $reader_load_errors{$key} = $writer_load_errors{$key} = $error;
4091 $self->[IX_FORMATS]{$key} = $value;
4097 my ($self, $key) = @_;
4099 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
4101 $self->[IX_CLASSES]{$key} or return undef;
4103 return $self->_check($key);
4107 die "%Imager::formats is not user monifiable";
4111 die "%Imager::formats is not user monifiable";
4115 die "%Imager::formats is not user monifiable";
4119 my ($self, $key) = @_;
4121 if (exists $self->[IX_FORMATS]{$key}) {
4122 my $value = $self->[IX_FORMATS]{$key}
4127 $self->_check($key) or return 1==0;
4135 unless (@{$self->[IX_LIST]}) {
4137 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4138 keys %{$self->[IX_FORMATS]};
4140 for my $key (keys %{$self->[IX_CLASSES]}) {
4141 $self->[IX_FORMATS]{$key} and next;
4143 and push @{$self->[IX_LIST]}, $key;
4147 @{$self->[IX_LIST]} or return;
4148 $self->[IX_INDEX] = 1;
4149 return $self->[IX_LIST][0];
4155 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4158 return $self->[IX_LIST][$self->[IX_INDEX]++];
4164 return scalar @{$self->[IX_LIST]};
4169 # Below is the stub of documentation for your module. You better edit it!
4173 Imager - Perl extension for Generating 24 bit Images
4183 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4188 # see Imager::Files for information on the read() method
4189 my $img = Imager->new(file=>$file)
4190 or die Imager->errstr();
4192 $file =~ s/\.[^.]*$//;
4194 # Create smaller version
4195 # documented in Imager::Transformations
4196 my $thumb = $img->scale(scalefactor=>.3);
4198 # Autostretch individual channels
4199 $thumb->filter(type=>'autolevels');
4201 # try to save in one of these formats
4204 for $format ( qw( png gif jpeg tiff ppm ) ) {
4205 # Check if given format is supported
4206 if ($Imager::formats{$format}) {
4207 $file.="_low.$format";
4208 print "Storing image as: $file\n";
4209 # documented in Imager::Files
4210 $thumb->write(file=>$file) or
4218 Imager is a module for creating and altering images. It can read and
4219 write various image formats, draw primitive shapes like lines,and
4220 polygons, blend multiple images together in various ways, scale, crop,
4221 render text and more.
4223 =head2 Overview of documentation
4229 Imager - This document - Synopsis, Example, Table of Contents and
4234 L<Imager::Tutorial> - a brief introduction to Imager.
4238 L<Imager::Cookbook> - how to do various things with Imager.
4242 L<Imager::ImageTypes> - Basics of constructing image objects with
4243 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4244 8/16/double bits/channel, color maps, channel masks, image tags, color
4245 quantization. Also discusses basic image information methods.
4249 L<Imager::Files> - IO interaction, reading/writing images, format
4254 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4259 L<Imager::Color> - Color specification.
4263 L<Imager::Fill> - Fill pattern specification.
4267 L<Imager::Font> - General font rendering, bounding boxes and font
4272 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4273 blending, pasting, convert and map.
4277 L<Imager::Engines> - Programmable transformations through
4278 C<transform()>, C<transform2()> and C<matrix_transform()>.
4282 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4287 L<Imager::Expr> - Expressions for evaluation engine used by
4292 L<Imager::Matrix2d> - Helper class for affine transformations.
4296 L<Imager::Fountain> - Helper for making gradient profiles.
4300 L<Imager::API> - using Imager's C API
4304 L<Imager::APIRef> - API function reference
4308 L<Imager::Inline> - using Imager's C API from Inline::C
4312 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4316 =head2 Basic Overview
4318 An Image object is created with C<$img = Imager-E<gt>new()>.
4321 $img=Imager->new(); # create empty image
4322 $img->read(file=>'lena.png',type=>'png') or # read image from file
4323 die $img->errstr(); # give an explanation
4324 # if something failed
4326 or if you want to create an empty image:
4328 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4330 This example creates a completely black image of width 400 and height
4333 =head1 ERROR HANDLING
4335 In general a method will return false when it fails, if it does use
4336 the C<errstr()> method to find out why:
4342 Returns the last error message in that context.
4344 If the last error you received was from calling an object method, such
4345 as read, call errstr() as an object method to find out why:
4347 my $image = Imager->new;
4348 $image->read(file => 'somefile.gif')
4349 or die $image->errstr;
4351 If it was a class method then call errstr() as a class method:
4353 my @imgs = Imager->read_multi(file => 'somefile.gif')
4354 or die Imager->errstr;
4356 Note that in some cases object methods are implemented in terms of
4357 class methods so a failing object method may set both.
4361 The C<Imager-E<gt>new> method is described in detail in
4362 L<Imager::ImageTypes>.
4366 Where to find information on methods for Imager class objects.
4368 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4371 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4373 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4376 arc() - L<Imager::Draw/arc()> - draw a filled arc
4378 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4381 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4383 circle() - L<Imager::Draw/circle()> - draw a filled circle
4385 close_log() - L<Imager::ImageTypes/close_log()> - close the Imager
4388 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4389 colors in an image's palette (paletted images only)
4391 combine() - L<Imager::Transformations/combine()> - combine channels
4392 from one or more images.
4394 combines() - L<Imager::Draw/combines()> - return a list of the
4395 different combine type keywords
4397 compose() - L<Imager::Transformations/compose()> - compose one image
4400 convert() - L<Imager::Transformations/convert()> - transform the color
4403 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4406 crop() - L<Imager::Transformations/crop()> - extract part of an image
4408 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4409 used to guess the output file format based on the output file name
4411 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4413 difference() - L<Imager::Filters/difference()> - produce a difference
4414 images from two input images.
4416 errstr() - L</errstr()> - the error from the last failed operation.
4418 filter() - L<Imager::Filters/filter()> - image filtering
4420 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4421 palette, if it has one
4423 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4426 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4429 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4430 samples per pixel for an image
4432 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4433 different colors used by an image (works for direct color images)
4435 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4436 palette, if it has one
4438 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4440 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4442 get_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4444 getheight() - L<Imager::ImageTypes/getheight()> - height of the image in
4447 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4449 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4452 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4453 row or partial row of pixels.
4455 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4456 row or partial row of pixels.
4458 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4461 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4464 init() - L<Imager::ImageTypes/init()>
4466 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4467 image write functions should write the image in their bilevel (blank
4468 and white, no gray levels) format
4470 is_logging() L<Imager::ImageTypes/is_logging()> - test if the debug
4473 line() - L<Imager::Draw/line()> - draw an interval
4475 load_plugin() - L<Imager::Filters/load_plugin()>
4477 log() - L<Imager::ImageTypes/log()> - send a message to the debugging
4480 make_palette() - L<Imager::ImageTypes/make_palette()> - produce a
4481 color palette from one or more input images.
4483 map() - L<Imager::Transformations/"Color Mappings"> - remap color
4486 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4488 matrix_transform() - L<Imager::Engines/matrix_transform()>
4490 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4492 NC() - L<Imager::Handy/NC()>
4494 NCF() - L<Imager::Handy/NCF()>
4496 new() - L<Imager::ImageTypes/new()>
4498 newcolor() - L<Imager::Handy/newcolor()>
4500 newcolour() - L<Imager::Handy/newcolour()>
4502 newfont() - L<Imager::Handy/newfont()>
4504 NF() - L<Imager::Handy/NF()>
4506 open() - L<Imager::Files> - an alias for read()
4508 open_log() - L<Imager::ImageTypes/open_log()> - open the debug log.
4512 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4515 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4518 polygon() - L<Imager::Draw/polygon()>
4520 polyline() - L<Imager::Draw/polyline()>
4522 preload() - L<Imager::Files/preload()>
4524 read() - L<Imager::Files/read()> - read a single image from an image file
4526 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
4529 read_types() - L<Imager::Files/read_types()> - list image types Imager
4532 register_filter() - L<Imager::Filters/register_filter()>
4534 register_reader() - L<Imager::Files/register_reader()>
4536 register_writer() - L<Imager::Files/register_writer()>
4538 rotate() - L<Imager::Transformations/rotate()>
4540 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
4541 onto an image and use the alpha channel
4543 scale() - L<Imager::Transformations/scale()>
4545 scale_calculate() - L<Imager::Transformations/scale_calculate()>
4547 scaleX() - L<Imager::Transformations/scaleX()>
4549 scaleY() - L<Imager::Transformations/scaleY()>
4551 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
4554 set_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
4556 setmask() - L<Imager::ImageTypes/setmask()>
4558 setpixel() - L<Imager::Draw/setpixel()>
4560 setsamples() - L<Imager::Draw/setsamples()>
4562 setscanline() - L<Imager::Draw/setscanline()>
4564 settag() - L<Imager::ImageTypes/settag()>
4566 string() - L<Imager::Draw/string()> - draw text on an image
4568 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
4570 to_paletted() - L<Imager::ImageTypes/to_paletted()>
4572 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
4574 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
4576 to_rgb_double() - L<Imager::ImageTypes/to_rgb_double()> - convert to
4577 double per sample image.
4579 transform() - L<Imager::Engines/"transform()">
4581 transform2() - L<Imager::Engines/"transform2()">
4583 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
4585 unload_plugin() - L<Imager::Filters/unload_plugin()>
4587 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
4590 write() - L<Imager::Files/write()> - write an image to a file
4592 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
4595 write_types() - L<Imager::Files/read_types()> - list image types Imager
4598 =head1 CONCEPT INDEX
4600 animated GIF - L<Imager::Files/"Writing an animated GIF">
4602 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
4603 L<Imager::ImageTypes/"Common Tags">.
4605 blend - alpha blending one image onto another
4606 L<Imager::Transformations/rubthrough()>
4608 blur - L<Imager::Filters/gaussian>, L<Imager::Filters/conv>
4610 boxes, drawing - L<Imager::Draw/box()>
4612 changes between image - L<Imager::Filters/"Image Difference">
4614 channels, combine into one image - L<Imager::Transformations/combine()>
4616 color - L<Imager::Color>
4618 color names - L<Imager::Color>, L<Imager::Color::Table>
4620 combine modes - L<Imager::Draw/"Combine Types">
4622 compare images - L<Imager::Filters/"Image Difference">
4624 contrast - L<Imager::Filters/contrast>, L<Imager::Filters/autolevels>
4626 convolution - L<Imager::Filters/conv>
4628 cropping - L<Imager::Transformations/crop()>
4630 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4632 C<diff> images - L<Imager::Filters/"Image Difference">
4634 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
4635 L<Imager::Cookbook/"Image spatial resolution">
4637 drawing boxes - L<Imager::Draw/box()>
4639 drawing lines - L<Imager::Draw/line()>
4641 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
4643 error message - L</"ERROR HANDLING">
4645 files, font - L<Imager::Font>
4647 files, image - L<Imager::Files>
4649 filling, types of fill - L<Imager::Fill>
4651 filling, boxes - L<Imager::Draw/box()>
4653 filling, flood fill - L<Imager::Draw/flood_fill()>
4655 flood fill - L<Imager::Draw/flood_fill()>
4657 fonts - L<Imager::Font>
4659 fonts, drawing with - L<Imager::Draw/string()>,
4660 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
4662 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4664 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
4666 fountain fill - L<Imager::Fill/"Fountain fills">,
4667 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4668 L<Imager::Filters/gradgen>
4670 GIF files - L<Imager::Files/"GIF">
4672 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
4674 gradient fill - L<Imager::Fill/"Fountain fills">,
4675 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4676 L<Imager::Filters/gradgen>
4678 gray scale, convert image to - L<Imager::Transformations/convert()>
4680 gaussian blur - L<Imager::Filters/gaussian>
4682 hatch fills - L<Imager::Fill/"Hatched fills">
4684 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4686 invert image - L<Imager::Filters/hardinvert>,
4687 L<Imager::Filters/hardinvertall>
4689 JPEG - L<Imager::Files/"JPEG">
4691 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
4693 lines, drawing - L<Imager::Draw/line()>
4695 matrix - L<Imager::Matrix2d>,
4696 L<Imager::Engines/"Matrix Transformations">,
4697 L<Imager::Font/transform()>
4699 metadata, image - L<Imager::ImageTypes/"Tags">
4701 mosaic - L<Imager::Filters/mosaic>
4703 noise, filter - L<Imager::Filters/noise>
4705 noise, rendered - L<Imager::Filters/turbnoise>,
4706 L<Imager::Filters/radnoise>
4708 paste - L<Imager::Transformations/paste()>,
4709 L<Imager::Transformations/rubthrough()>
4711 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
4712 L<Imager::ImageTypes/new()>
4714 =for stopwords posterize
4716 posterize - L<Imager::Filters/postlevels>
4718 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
4720 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
4722 rectangles, drawing - L<Imager::Draw/box()>
4724 resizing an image - L<Imager::Transformations/scale()>,
4725 L<Imager::Transformations/crop()>
4727 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
4729 saving an image - L<Imager::Files>
4731 scaling - L<Imager::Transformations/scale()>
4733 SGI files - L<Imager::Files/"SGI (RGB, BW)">
4735 sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
4737 size, image - L<Imager::ImageTypes/getwidth()>,
4738 L<Imager::ImageTypes/getheight()>
4740 size, text - L<Imager::Font/bounding_box()>
4742 tags, image metadata - L<Imager::ImageTypes/"Tags">
4744 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
4745 L<Imager::Font::Wrap>
4747 text, wrapping text in an area - L<Imager::Font::Wrap>
4749 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4751 tiles, color - L<Imager::Filters/mosaic>
4753 transparent images - L<Imager::ImageTypes>,
4754 L<Imager::Cookbook/"Transparent PNG">
4756 =for stopwords unsharp
4758 unsharp mask - L<Imager::Filters/unsharpmask>
4760 watermark - L<Imager::Filters/watermark>
4762 writing an image to a file - L<Imager::Files>
4766 Imager doesn't support perl threads.
4768 Imager has limited code to prevent double frees if you create images,
4769 colors etc, and then create a thread, but has no code to prevent two
4770 threads entering Imager's error handling code, and none is likely to
4775 The best place to get help with Imager is the mailing list.
4777 To subscribe send a message with C<subscribe> in the body to:
4779 imager-devel+request@molar.is
4785 L<http://www.molar.is/en/lists/imager-devel/>
4789 where you can also find the mailing list archive.
4791 You can report bugs by pointing your browser at:
4795 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
4799 or by sending an email to:
4803 bug-Imager@rt.cpan.org
4807 Please remember to include the versions of Imager, perl, supporting
4808 libraries, and any relevant code. If you have specific images that
4809 cause the problems, please include those too.
4811 If you don't want to publish your email address on a mailing list you
4812 can use CPAN::Forum:
4814 http://www.cpanforum.com/dist/Imager
4816 You will need to register to post.
4818 =head1 CONTRIBUTING TO IMAGER
4824 If you like or dislike Imager, you can add a public review of Imager
4827 http://cpanratings.perl.org/dist/Imager
4829 =for stopwords Bitcard
4831 This requires a Bitcard account (http://www.bitcard.org).
4833 You can also send email to the maintainer below.
4835 If you send me a bug report via email, it will be copied to Request
4840 I accept patches, preferably against the master branch in git. Please
4841 include an explanation of the reason for why the patch is needed or
4844 Your patch should include regression tests where possible, otherwise
4845 it will be delayed until I get a chance to write them.
4847 To browse Imager's git repository:
4849 http://git.imager.perl.org/imager.git
4853 https://github.com/tonycoz/imager
4857 git clone git://git.imager.perl.org/imager.git
4861 git clone git://github.com/tonycoz/imager.git
4865 Tony Cook <tonyc@cpan.org> is the current maintainer for Imager.
4867 Arnar M. Hrafnkelsson is the original author of Imager.
4869 Many others have contributed to Imager, please see the C<README> for a
4874 Imager is licensed under the same terms as perl itself.
4877 makeblendedfont Fontforge
4879 A test font, FT2/fontfiles/MMOne.pfb, contains a Postscript operator
4880 definition copyrighted by Adobe. See F<adobe.txt> in the source for
4881 license information.
4885 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
4886 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
4887 L<Imager::Font>(3), L<Imager::Transformations>(3),
4888 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
4889 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
4891 L<http://imager.perl.org/>
4893 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
4895 Other perl imaging modules include:
4897 L<GD>(3), L<Image::Magick>(3), L<Graphics::Magick>(3).