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) {
153 XSLoader::load(Imager => $VERSION);
159 png => "Imager::File::PNG",
160 gif => "Imager::File::GIF",
161 tiff => "Imager::File::TIFF",
162 jpeg => "Imager::File::JPEG",
163 w32 => "Imager::Font::W32",
164 ft2 => "Imager::Font::FT2",
165 t1 => "Imager::Font::T1",
168 tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
171 for(i_list_formats()) { $formats_low{$_}++; }
173 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
177 # the members of the subhashes under %filters are:
178 # callseq - a list of the parameters to the underlying filter in the
179 # order they are passed
180 # callsub - a code ref that takes a named parameter list and calls the
182 # defaults - a hash of default values
183 # names - defines names for value of given parameters so if the names
184 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
185 # foo parameter, the filter will receive 1 for the foo
188 callseq => ['image','intensity'],
189 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
193 callseq => ['image', 'amount', 'subtype'],
194 defaults => { amount=>3,subtype=>0 },
195 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
198 $filters{hardinvert} ={
199 callseq => ['image'],
201 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
204 $filters{hardinvertall} =
206 callseq => ['image'],
208 callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
211 $filters{autolevels} ={
212 callseq => ['image','lsat','usat','skew'],
213 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
214 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
217 $filters{turbnoise} ={
218 callseq => ['image'],
219 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
220 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
223 $filters{radnoise} ={
224 callseq => ['image'],
225 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
226 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
231 callseq => ['image', 'coef'],
236 i_conv($hsh{image},$hsh{coef})
237 or die Imager->_error_as_msg() . "\n";
243 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
244 defaults => { dist => 0 },
248 my @colors = @{$hsh{colors}};
251 i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
255 $filters{nearest_color} =
257 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
262 # make sure the segments are specified with colors
264 for my $color (@{$hsh{colors}}) {
265 my $new_color = _color($color)
266 or die $Imager::ERRSTR."\n";
267 push @colors, $new_color;
270 i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors,
272 or die Imager->_error_as_msg() . "\n";
275 $filters{gaussian} = {
276 callseq => [ 'image', 'stddev' ],
278 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
282 callseq => [ qw(image size) ],
283 defaults => { size => 20 },
284 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
288 callseq => [ qw(image bump elevation lightx lighty st) ],
289 defaults => { elevation=>0, st=> 2 },
292 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
293 $hsh{lightx}, $hsh{lighty}, $hsh{st});
296 $filters{bumpmap_complex} =
298 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
315 for my $cname (qw/Ia Il Is/) {
316 my $old = $hsh{$cname};
317 my $new_color = _color($old)
318 or die $Imager::ERRSTR, "\n";
319 $hsh{$cname} = $new_color;
321 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
322 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
323 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
327 $filters{postlevels} =
329 callseq => [ qw(image levels) ],
330 defaults => { levels => 10 },
331 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
333 $filters{watermark} =
335 callseq => [ qw(image wmark tx ty pixdiff) ],
336 defaults => { pixdiff=>10, tx=>0, ty=>0 },
340 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
346 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
348 ftype => { linear => 0,
354 repeat => { none => 0,
369 multiply => 2, mult => 2,
372 subtract => 5, 'sub' => 5,
382 defaults => { ftype => 0, repeat => 0, combine => 0,
383 super_sample => 0, ssample_param => 4,
396 # make sure the segments are specified with colors
398 for my $segment (@{$hsh{segments}}) {
399 my @new_segment = @$segment;
401 $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
402 push @segments, \@new_segment;
405 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
406 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
407 $hsh{ssample_param}, \@segments)
408 or die Imager->_error_as_msg() . "\n";
411 $filters{unsharpmask} =
413 callseq => [ qw(image stddev scale) ],
414 defaults => { stddev=>2.0, scale=>1.0 },
418 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
422 $FORMATGUESS=\&def_guess_type;
432 # NOTE: this might be moved to an import override later on
437 if ($_[$i] eq '-log-stderr') {
445 goto &Exporter::import;
449 Imager->open_log(log => $_[0], level => $_[1]);
454 my %parms=(loglevel=>1,@_);
456 if (exists $parms{'warn_obsolete'}) {
457 $warn_obsolete = $parms{'warn_obsolete'};
461 Imager->open_log(log => $parms{log}, level => $parms{loglevel})
465 if (exists $parms{'t1log'}) {
467 if (Imager::Font::T1::i_init_t1($parms{'t1log'})) {
468 Imager->_set_error(Imager->_error_as_msg);
482 my (%opts) = ( loglevel => 1, @_ );
484 $is_logging = i_init_log($opts{log}, $opts{loglevel});
485 unless ($is_logging) {
486 Imager->_set_error(Imager->_error_as_msg());
490 Imager->log("Imager $VERSION starting\n", 1);
496 i_init_log(undef, -1);
501 my ($class, $message, $level) = @_;
503 defined $level or $level = 1;
505 i_log_entry($message, $level);
515 print "shutdown code\n";
516 # for(keys %instances) { $instances{$_}->DESTROY(); }
517 malloc_state(); # how do decide if this should be used? -- store something from the import
518 print "Imager exiting\n";
522 # Load a filter plugin
527 my ($DSO_handle,$str)=DSO_open($filename);
528 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
529 my %funcs=DSO_funclist($DSO_handle);
530 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
532 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
534 $DSOs{$filename}=[$DSO_handle,\%funcs];
537 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
538 $DEBUG && print "eval string:\n",$evstr,"\n";
550 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
551 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
552 for(keys %{$funcref}) {
554 $DEBUG && print "unloading: $_\n";
556 my $rc=DSO_close($DSO_handle);
557 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
561 # take the results of i_error() and make a message out of it
563 return join(": ", map $_->[0], i_errors());
566 # this function tries to DWIM for color parameters
567 # color objects are used as is
568 # simple scalars are simply treated as single parameters to Imager::Color->new
569 # hashrefs are treated as named argument lists to Imager::Color->new
570 # arrayrefs are treated as list arguments to Imager::Color->new iff any
572 # other arrayrefs are treated as list arguments to Imager::Color::Float
576 # perl 5.6.0 seems to do weird things to $arg if we don't make an
577 # explicitly stringified copy
578 # I vaguely remember a bug on this on p5p, but couldn't find it
579 # through bugs.perl.org (I had trouble getting it to find any bugs)
580 my $copy = $arg . "";
584 if (UNIVERSAL::isa($arg, "Imager::Color")
585 || UNIVERSAL::isa($arg, "Imager::Color::Float")) {
589 if ($copy =~ /^HASH\(/) {
590 $result = Imager::Color->new(%$arg);
592 elsif ($copy =~ /^ARRAY\(/) {
593 $result = Imager::Color->new(@$arg);
596 $Imager::ERRSTR = "Not a color";
601 # assume Imager::Color::new knows how to handle it
602 $result = Imager::Color->new($arg);
609 my ($self, $combine, $default) = @_;
611 if (!defined $combine && ref $self) {
612 $combine = $self->{combine};
614 defined $combine or $combine = $defaults{combine};
615 defined $combine or $combine = $default;
617 if (exists $combine_types{$combine}) {
618 $combine = $combine_types{$combine};
625 my ($self, $method) = @_;
627 $self->{IMG} and return 1;
629 my $msg = 'empty input image';
630 $msg = "$method: $msg" if $method;
631 $self->_set_error($msg);
636 # returns first defined parameter
639 return $_ if defined $_;
645 # Methods to be called on objects.
648 # Create a new Imager object takes very few parameters.
649 # usually you call this method and then call open from
650 # the resulting object
657 $self->{IMG}=undef; # Just to indicate what exists
658 $self->{ERRSTR}=undef; #
659 $self->{DEBUG}=$DEBUG;
660 $self->{DEBUG} and print "Initialized Imager\n";
661 if (defined $hsh{xsize} || defined $hsh{ysize}) {
662 unless ($self->img_set(%hsh)) {
663 $Imager::ERRSTR = $self->{ERRSTR};
667 elsif (defined $hsh{file} ||
670 defined $hsh{callback} ||
671 defined $hsh{readcb} ||
672 defined $hsh{data}) {
673 # allow $img = Imager->new(file => $filename)
676 # type is already used as a parameter to new(), rename it for the
678 if ($hsh{filetype}) {
679 $extras{type} = $hsh{filetype};
681 unless ($self->read(%hsh, %extras)) {
682 $Imager::ERRSTR = $self->{ERRSTR};
690 # Copy an entire image with no changes
691 # - if an image has magic the copy of it will not be magical
695 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
697 unless (defined wantarray) {
699 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
703 my $newcopy=Imager->new();
704 $newcopy->{IMG} = i_copy($self->{IMG});
713 unless ($self->{IMG}) {
714 $self->_set_error('empty input image');
717 my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
718 my $src = $input{img} || $input{src};
720 $self->_set_error("no source image");
723 $input{left}=0 if $input{left} <= 0;
724 $input{top}=0 if $input{top} <= 0;
726 my($r,$b)=i_img_info($src->{IMG});
727 my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
728 my ($src_right, $src_bottom);
729 if ($input{src_coords}) {
730 ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
733 if (defined $input{src_maxx}) {
734 $src_right = $input{src_maxx};
736 elsif (defined $input{width}) {
737 if ($input{width} <= 0) {
738 $self->_set_error("paste: width must me positive");
741 $src_right = $src_left + $input{width};
746 if (defined $input{src_maxy}) {
747 $src_bottom = $input{src_maxy};
749 elsif (defined $input{height}) {
750 if ($input{height} < 0) {
751 $self->_set_error("paste: height must be positive");
754 $src_bottom = $src_top + $input{height};
761 $src_right > $r and $src_right = $r;
762 $src_bottom > $b and $src_bottom = $b;
764 if ($src_right <= $src_left
765 || $src_bottom < $src_top) {
766 $self->_set_error("nothing to paste");
770 i_copyto($self->{IMG}, $src->{IMG},
771 $src_left, $src_top, $src_right, $src_bottom,
772 $input{left}, $input{top});
774 return $self; # What should go here??
777 # Crop an image - i.e. return a new image that is smaller
781 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
783 unless (defined wantarray) {
785 warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
791 my ($w, $h, $l, $r, $b, $t) =
792 @hsh{qw(width height left right bottom top)};
794 # work through the various possibilities
799 elsif (!defined $r) {
800 $r = $self->getwidth;
812 $l = int(0.5+($self->getwidth()-$w)/2);
817 $r = $self->getwidth;
823 elsif (!defined $b) {
824 $b = $self->getheight;
836 $t=int(0.5+($self->getheight()-$h)/2);
841 $b = $self->getheight;
844 ($l,$r)=($r,$l) if $l>$r;
845 ($t,$b)=($b,$t) if $t>$b;
848 $r > $self->getwidth and $r = $self->getwidth;
850 $b > $self->getheight and $b = $self->getheight;
852 if ($l == $r || $t == $b) {
853 $self->_set_error("resulting image would have no content");
856 if( $r < $l or $b < $t ) {
857 $self->_set_error("attempting to crop outside of the image");
860 my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
862 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
867 my ($self, %opts) = @_;
869 $self->{IMG} or return $self->_set_error("Not a valid image");
871 my $x = $opts{xsize} || $self->getwidth;
872 my $y = $opts{ysize} || $self->getheight;
873 my $channels = $opts{channels} || $self->getchannels;
875 my $out = Imager->new;
876 if ($channels == $self->getchannels) {
877 $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
880 $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
882 unless ($out->{IMG}) {
883 $self->{ERRSTR} = $self->_error_as_msg;
890 # Sets an image to a certain size and channel number
891 # if there was previously data in the image it is discarded
896 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
898 if (defined($self->{IMG})) {
899 # let IIM_DESTROY destroy it, it's possible this image is
900 # referenced from a virtual image (like masked)
901 #i_img_destroy($self->{IMG});
905 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
906 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
907 $hsh{maxcolors} || 256);
909 elsif ($hsh{bits} eq 'double') {
910 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
912 elsif ($hsh{bits} == 16) {
913 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
916 $self->{IMG}= i_img_8_new($hsh{'xsize'}, $hsh{'ysize'},
920 unless ($self->{IMG}) {
921 $self->{ERRSTR} = Imager->_error_as_msg();
928 # created a masked version of the current image
932 $self or return undef;
933 my %opts = (left => 0,
935 right => $self->getwidth,
936 bottom => $self->getheight,
938 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
940 my $result = Imager->new;
941 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
942 $opts{top}, $opts{right} - $opts{left},
943 $opts{bottom} - $opts{top});
944 unless ($result->{IMG}) {
945 $self->_set_error(Imager->_error_as_msg);
949 # keep references to the mask and base images so they don't
951 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
956 # convert an RGB image into a paletted image
960 if (@_ != 1 && !ref $_[0]) {
967 unless (defined wantarray) {
969 warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
976 my $result = Imager->new;
977 unless ($result->{IMG} = i_img_to_pal($self->{IMG}, $opts)) {
978 $self->_set_error(Imager->_error_as_msg);
986 my ($class, $quant, @images) = @_;
989 Imager->_set_error("make_palette: supply at least one image");
993 for my $img (@images) {
994 unless ($img->{IMG}) {
995 Imager->_set_error("make_palette: image $index is empty");
1001 return i_img_make_palette($quant, map $_->{IMG}, @images);
1004 # convert a paletted (or any image) to an 8-bit/channel RGB image
1008 unless (defined wantarray) {
1009 my @caller = caller;
1010 warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
1017 my $result = Imager->new;
1018 unless ($result->{IMG} = i_img_to_rgb($self->{IMG})) {
1019 $self->_set_error(Imager->_error_as_msg());
1026 # convert a paletted (or any image) to a 16-bit/channel RGB image
1030 unless (defined wantarray) {
1031 my @caller = caller;
1032 warn "to_rgb16() called in void context - to_rgb16() returns the converted image at $caller[1] line $caller[2]\n";
1039 my $result = Imager->new;
1040 unless ($result->{IMG} = i_img_to_rgb16($self->{IMG})) {
1041 $self->_set_error(Imager->_error_as_msg());
1048 # convert a paletted (or any image) to an double/channel RGB image
1052 unless (defined wantarray) {
1053 my @caller = caller;
1054 warn "to_rgb16() called in void context - to_rgb_double() returns the converted image at $caller[1] line $caller[2]\n";
1061 my $result = Imager->new;
1062 unless ($result->{IMG} = i_img_to_drgb($self->{IMG})) {
1063 $self->_set_error(Imager->_error_as_msg());
1072 my %opts = (colors=>[], @_);
1074 unless ($self->{IMG}) {
1075 $self->_set_error("empty input image");
1079 my @colors = @{$opts{colors}}
1082 for my $color (@colors) {
1083 $color = _color($color);
1085 $self->_set_error($Imager::ERRSTR);
1090 return i_addcolors($self->{IMG}, @colors);
1095 my %opts = (start=>0, colors=>[], @_);
1097 unless ($self->{IMG}) {
1098 $self->_set_error("empty input image");
1102 my @colors = @{$opts{colors}}
1105 for my $color (@colors) {
1106 $color = _color($color);
1108 $self->_set_error($Imager::ERRSTR);
1113 return i_setcolors($self->{IMG}, $opts{start}, @colors);
1119 if (!exists $opts{start} && !exists $opts{count}) {
1122 $opts{count} = $self->colorcount;
1124 elsif (!exists $opts{count}) {
1127 elsif (!exists $opts{start}) {
1132 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
1136 i_colorcount($_[0]{IMG});
1140 i_maxcolors($_[0]{IMG});
1146 $opts{color} or return undef;
1148 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
1153 my $bits = $self->{IMG} && i_img_bits($self->{IMG});
1154 if ($bits && $bits == length(pack("d", 1)) * 8) {
1163 return i_img_type($self->{IMG}) ? "paletted" : "direct";
1169 $self->{IMG} and i_img_virtual($self->{IMG});
1175 $self->{IMG} or return;
1177 return i_img_is_monochrome($self->{IMG});
1181 my ($self, %opts) = @_;
1183 $self->{IMG} or return;
1185 if (defined $opts{name}) {
1189 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
1190 push @result, (i_tags_get($self->{IMG}, $found))[1];
1193 return wantarray ? @result : $result[0];
1195 elsif (defined $opts{code}) {
1199 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
1200 push @result, (i_tags_get($self->{IMG}, $found))[1];
1207 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
1210 return i_tags_count($self->{IMG});
1219 return -1 unless $self->{IMG};
1221 if (defined $opts{value}) {
1222 if ($opts{value} =~ /^\d+$/) {
1224 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
1227 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
1230 elsif (defined $opts{data}) {
1231 # force addition as a string
1232 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
1235 $self->{ERRSTR} = "No value supplied";
1239 elsif ($opts{code}) {
1240 if (defined $opts{value}) {
1241 if ($opts{value} =~ /^\d+$/) {
1243 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
1246 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
1249 elsif (defined $opts{data}) {
1250 # force addition as a string
1251 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
1254 $self->{ERRSTR} = "No value supplied";
1267 return 0 unless $self->{IMG};
1269 if (defined $opts{'index'}) {
1270 return i_tags_delete($self->{IMG}, $opts{'index'});
1272 elsif (defined $opts{name}) {
1273 return i_tags_delbyname($self->{IMG}, $opts{name});
1275 elsif (defined $opts{code}) {
1276 return i_tags_delbycode($self->{IMG}, $opts{code});
1279 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
1285 my ($self, %opts) = @_;
1288 $self->deltag(name=>$opts{name});
1289 return $self->addtag(name=>$opts{name}, value=>$opts{value});
1291 elsif (defined $opts{code}) {
1292 $self->deltag(code=>$opts{code});
1293 return $self->addtag(code=>$opts{code}, value=>$opts{value});
1301 sub _get_reader_io {
1302 my ($self, $input) = @_;
1305 return $input->{io}, undef;
1307 elsif ($input->{fd}) {
1308 return io_new_fd($input->{fd});
1310 elsif ($input->{fh}) {
1311 my $fd = fileno($input->{fh});
1312 unless (defined $fd) {
1313 $self->_set_error("Handle in fh option not opened");
1316 return io_new_fd($fd);
1318 elsif ($input->{file}) {
1319 my $file = IO::File->new($input->{file}, "r");
1321 $self->_set_error("Could not open $input->{file}: $!");
1325 return (io_new_fd(fileno($file)), $file);
1327 elsif ($input->{data}) {
1328 return io_new_buffer($input->{data});
1330 elsif ($input->{callback} || $input->{readcb}) {
1331 if (!$input->{seekcb}) {
1332 $self->_set_error("Need a seekcb parameter");
1334 if ($input->{maxbuffer}) {
1335 return io_new_cb($input->{writecb},
1336 $input->{callback} || $input->{readcb},
1337 $input->{seekcb}, $input->{closecb},
1338 $input->{maxbuffer});
1341 return io_new_cb($input->{writecb},
1342 $input->{callback} || $input->{readcb},
1343 $input->{seekcb}, $input->{closecb});
1347 $self->_set_error("file/fd/fh/data/callback parameter missing");
1352 sub _get_writer_io {
1353 my ($self, $input) = @_;
1355 my $buffered = exists $input->{buffered} ? $input->{buffered} : 1;
1362 elsif ($input->{fd}) {
1363 $io = io_new_fd($input->{fd});
1365 elsif ($input->{fh}) {
1366 my $fd = fileno($input->{fh});
1367 unless (defined $fd) {
1368 $self->_set_error("Handle in fh option not opened");
1372 my $oldfh = select($input->{fh});
1373 # flush anything that's buffered, and make sure anything else is flushed
1376 $io = io_new_fd($fd);
1378 elsif ($input->{file}) {
1379 my $fh = new IO::File($input->{file},"w+");
1381 $self->_set_error("Could not open file $input->{file}: $!");
1384 binmode($fh) or die;
1385 $io = io_new_fd(fileno($fh));
1388 elsif ($input->{data}) {
1389 $io = io_new_bufchain();
1391 elsif ($input->{callback} || $input->{writecb}) {
1392 if ($input->{maxbuffer} && $input->{maxbuffer} == 1) {
1395 $io = io_new_cb($input->{callback} || $input->{writecb},
1397 $input->{seekcb}, $input->{closecb});
1400 $self->_set_error("file/fd/fh/data/callback parameter missing");
1404 unless ($buffered) {
1405 $io->set_buffered(0);
1408 return ($io, @extras);
1411 # Read an image from file
1417 if (defined($self->{IMG})) {
1418 # let IIM_DESTROY do the destruction, since the image may be
1419 # referenced from elsewhere
1420 #i_img_destroy($self->{IMG});
1421 undef($self->{IMG});
1424 my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
1426 my $type = $input{'type'};
1428 $type = i_test_format_probe($IO, -1);
1431 if ($input{file} && !$type) {
1433 $type = $FORMATGUESS->($input{file});
1437 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1438 $input{file} and $msg .= " or file name";
1439 $self->_set_error($msg);
1443 _reader_autoload($type);
1445 if ($readers{$type} && $readers{$type}{single}) {
1446 return $readers{$type}{single}->($self, $IO, %input);
1449 unless ($formats_low{$type}) {
1450 my $read_types = join ', ', sort Imager->read_types();
1451 $self->_set_error("format '$type' not supported - formats $read_types available for reading - $reader_load_errors{$type}");
1455 my $allow_incomplete = $input{allow_incomplete};
1456 defined $allow_incomplete or $allow_incomplete = 0;
1458 if ( $type eq 'pnm' ) {
1459 $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
1460 if ( !defined($self->{IMG}) ) {
1461 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
1464 $self->{DEBUG} && print "loading a pnm file\n";
1468 if ( $type eq 'bmp' ) {
1469 $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
1470 if ( !defined($self->{IMG}) ) {
1471 $self->{ERRSTR}=$self->_error_as_msg();
1474 $self->{DEBUG} && print "loading a bmp file\n";
1477 if ( $type eq 'tga' ) {
1478 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
1479 if ( !defined($self->{IMG}) ) {
1480 $self->{ERRSTR}=$self->_error_as_msg();
1483 $self->{DEBUG} && print "loading a tga file\n";
1486 if ( $type eq 'raw' ) {
1487 unless ( $input{xsize} && $input{ysize} ) {
1488 $self->_set_error('missing xsize or ysize parameter for raw');
1492 my $interleave = _first($input{raw_interleave}, $input{interleave});
1493 unless (defined $interleave) {
1494 my @caller = caller;
1495 warn "read(type => 'raw') $caller[2] line $caller[1]: supply interleave or raw_interleave for future compatibility\n";
1498 my $data_ch = _first($input{raw_datachannels}, $input{datachannels}, 3);
1499 my $store_ch = _first($input{raw_storechannels}, $input{storechannels}, 3);
1501 $self->{IMG} = i_readraw_wiol( $IO,
1507 if ( !defined($self->{IMG}) ) {
1508 $self->{ERRSTR}=$self->_error_as_msg();
1511 $self->{DEBUG} && print "loading a raw file\n";
1517 sub register_reader {
1518 my ($class, %opts) = @_;
1521 or die "register_reader called with no type parameter\n";
1523 my $type = $opts{type};
1525 defined $opts{single} || defined $opts{multiple}
1526 or die "register_reader called with no single or multiple parameter\n";
1528 $readers{$type} = { };
1529 if ($opts{single}) {
1530 $readers{$type}{single} = $opts{single};
1532 if ($opts{multiple}) {
1533 $readers{$type}{multiple} = $opts{multiple};
1539 sub register_writer {
1540 my ($class, %opts) = @_;
1543 or die "register_writer called with no type parameter\n";
1545 my $type = $opts{type};
1547 defined $opts{single} || defined $opts{multiple}
1548 or die "register_writer called with no single or multiple parameter\n";
1550 $writers{$type} = { };
1551 if ($opts{single}) {
1552 $writers{$type}{single} = $opts{single};
1554 if ($opts{multiple}) {
1555 $writers{$type}{multiple} = $opts{multiple};
1566 grep($file_formats{$_}, keys %formats),
1567 qw(ico sgi), # formats not handled directly, but supplied with Imager
1578 grep($file_formats{$_}, keys %formats),
1579 qw(ico sgi), # formats not handled directly, but supplied with Imager
1586 my ($file, $error) = @_;
1588 if ($attempted_to_load{$file}) {
1589 if ($file_load_errors{$file}) {
1590 $$error = $file_load_errors{$file};
1598 local $SIG{__DIE__};
1600 ++$attempted_to_load{$file};
1608 my $work = $@ || "Unknown error";
1610 $work =~ s/\n?Compilation failed in require at .*Imager\.pm line .*\z//m;
1611 $work =~ s/\n/\\n/g;
1612 $work =~ s/\s*\.?\z/ loading $file/;
1613 $file_load_errors{$file} = $work;
1620 # probes for an Imager::File::whatever module
1621 sub _reader_autoload {
1624 return if $formats_low{$type} || $readers{$type};
1626 return unless $type =~ /^\w+$/;
1628 my $file = "Imager/File/\U$type\E.pm";
1631 my $loaded = _load_file($file, \$error);
1632 if (!$loaded && $error =~ /^Can't locate /) {
1633 my $filer = "Imager/File/\U$type\EReader.pm";
1634 $loaded = _load_file($filer, \$error);
1635 if ($error =~ /^Can't locate /) {
1636 $error = "Can't locate $file or $filer";
1640 $reader_load_errors{$type} = $error;
1644 # probes for an Imager::File::whatever module
1645 sub _writer_autoload {
1648 return if $formats_low{$type} || $writers{$type};
1650 return unless $type =~ /^\w+$/;
1652 my $file = "Imager/File/\U$type\E.pm";
1655 my $loaded = _load_file($file, \$error);
1656 if (!$loaded && $error =~ /^Can't locate /) {
1657 my $filew = "Imager/File/\U$type\EWriter.pm";
1658 $loaded = _load_file($filew, \$error);
1659 if ($error =~ /^Can't locate /) {
1660 $error = "Can't locate $file or $filew";
1664 $writer_load_errors{$type} = $error;
1668 sub _fix_gif_positions {
1669 my ($opts, $opt, $msg, @imgs) = @_;
1671 my $positions = $opts->{'gif_positions'};
1673 for my $pos (@$positions) {
1674 my ($x, $y) = @$pos;
1675 my $img = $imgs[$index++];
1676 $img->settag(name=>'gif_left', value=>$x);
1677 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1679 $$msg .= "replaced with the gif_left and gif_top tags";
1684 gif_each_palette=>'gif_local_map',
1685 interlace => 'gif_interlace',
1686 gif_delays => 'gif_delay',
1687 gif_positions => \&_fix_gif_positions,
1688 gif_loop_count => 'gif_loop',
1691 # options that should be converted to colors
1692 my %color_opts = map { $_ => 1 } qw/i_background/;
1695 my ($self, $opts, $prefix, @imgs) = @_;
1697 for my $opt (keys %$opts) {
1699 if ($obsolete_opts{$opt}) {
1700 my $new = $obsolete_opts{$opt};
1701 my $msg = "Obsolete option $opt ";
1703 $new->($opts, $opt, \$msg, @imgs);
1706 $msg .= "replaced with the $new tag ";
1709 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1710 warn $msg if $warn_obsolete && $^W;
1712 next unless $tagname =~ /^\Q$prefix/;
1713 my $value = $opts->{$opt};
1714 if ($color_opts{$opt}) {
1715 $value = _color($value);
1717 $self->_set_error($Imager::ERRSTR);
1722 if (UNIVERSAL::isa($value, "Imager::Color")) {
1723 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1724 for my $img (@imgs) {
1725 $img->settag(name=>$tagname, value=>$tag);
1728 elsif (ref($value) eq 'ARRAY') {
1729 for my $i (0..$#$value) {
1730 my $val = $value->[$i];
1732 if (UNIVERSAL::isa($val, "Imager::Color")) {
1733 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1735 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1738 $self->_set_error("Unknown reference type " . ref($value) .
1739 " supplied in array for $opt");
1745 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1750 $self->_set_error("Unknown reference type " . ref($value) .
1751 " supplied for $opt");
1756 # set it as a tag for every image
1757 for my $img (@imgs) {
1758 $img->settag(name=>$tagname, value=>$value);
1766 # Write an image to file
1769 my %input=(jpegquality=>75,
1779 $self->_set_opts(\%input, "i_", $self)
1782 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1784 my $type = $input{'type'};
1785 if (!$type and $input{file}) {
1786 $type = $FORMATGUESS->($input{file});
1789 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1793 _writer_autoload($type);
1796 if ($writers{$type} && $writers{$type}{single}) {
1797 ($IO, $fh) = $self->_get_writer_io(\%input)
1800 $writers{$type}{single}->($self, $IO, %input, type => $type)
1804 if (!$formats_low{$type}) {
1805 my $write_types = join ', ', sort Imager->write_types();
1806 $self->_set_error("format '$type' not supported - formats $write_types available for writing - $writer_load_errors{$type}");
1810 ($IO, $fh) = $self->_get_writer_io(\%input, $type)
1813 if ( $type eq 'pnm' ) {
1814 $self->_set_opts(\%input, "pnm_", $self)
1816 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1817 $self->{ERRSTR} = $self->_error_as_msg();
1820 $self->{DEBUG} && print "writing a pnm file\n";
1822 elsif ( $type eq 'raw' ) {
1823 $self->_set_opts(\%input, "raw_", $self)
1825 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1826 $self->{ERRSTR} = $self->_error_as_msg();
1829 $self->{DEBUG} && print "writing a raw file\n";
1831 elsif ( $type eq 'bmp' ) {
1832 $self->_set_opts(\%input, "bmp_", $self)
1834 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1835 $self->{ERRSTR} = $self->_error_as_msg;
1838 $self->{DEBUG} && print "writing a bmp file\n";
1840 elsif ( $type eq 'tga' ) {
1841 $self->_set_opts(\%input, "tga_", $self)
1844 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1845 $self->{ERRSTR}=$self->_error_as_msg();
1848 $self->{DEBUG} && print "writing a tga file\n";
1852 if (exists $input{'data'}) {
1853 my $data = io_slurp($IO);
1855 $self->{ERRSTR}='Could not slurp from buffer';
1858 ${$input{data}} = $data;
1864 my ($class, $opts, @images) = @_;
1866 my $type = $opts->{type};
1868 if (!$type && $opts->{'file'}) {
1869 $type = $FORMATGUESS->($opts->{'file'});
1872 $class->_set_error('type parameter missing and not possible to guess from extension');
1875 # translate to ImgRaw
1876 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1877 $class->_set_error('Usage: Imager->write_multi({ options }, @images)');
1880 $class->_set_opts($opts, "i_", @images)
1882 my @work = map $_->{IMG}, @images;
1884 _writer_autoload($type);
1887 if ($writers{$type} && $writers{$type}{multiple}) {
1888 ($IO, $file) = $class->_get_writer_io($opts, $type)
1891 $writers{$type}{multiple}->($class, $IO, $opts, @images)
1895 if (!$formats{$type}) {
1896 my $write_types = join ', ', sort Imager->write_types();
1897 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
1901 ($IO, $file) = $class->_get_writer_io($opts, $type)
1904 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
1908 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
1913 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
1919 if (exists $opts->{'data'}) {
1920 my $data = io_slurp($IO);
1922 Imager->_set_error('Could not slurp from buffer');
1925 ${$opts->{data}} = $data;
1930 # read multiple images from a file
1932 my ($class, %opts) = @_;
1934 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
1937 my $type = $opts{'type'};
1939 $type = i_test_format_probe($IO, -1);
1942 if ($opts{file} && !$type) {
1944 $type = $FORMATGUESS->($opts{file});
1948 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1949 $opts{file} and $msg .= " or file name";
1950 Imager->_set_error($msg);
1954 _reader_autoload($type);
1956 if ($readers{$type} && $readers{$type}{multiple}) {
1957 return $readers{$type}{multiple}->($IO, %opts);
1960 unless ($formats{$type}) {
1961 my $read_types = join ', ', sort Imager->read_types();
1962 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
1967 if ($type eq 'pnm') {
1968 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
1971 my $img = Imager->new;
1972 if ($img->read(%opts, io => $IO, type => $type)) {
1975 Imager->_set_error($img->errstr);
1980 $ERRSTR = _error_as_msg();
1984 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1988 # Destroy an Imager object
1992 # delete $instances{$self};
1993 if (defined($self->{IMG})) {
1994 # the following is now handled by the XS DESTROY method for
1995 # Imager::ImgRaw object
1996 # Re-enabling this will break virtual images
1997 # tested for in t/t020masked.t
1998 # i_img_destroy($self->{IMG});
1999 undef($self->{IMG});
2001 # print "Destroy Called on an empty image!\n"; # why did I put this here??
2005 # Perform an inplace filter of an image
2006 # that is the image will be overwritten with the data
2012 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2014 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
2016 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
2017 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
2020 if ($filters{$input{'type'}}{names}) {
2021 my $names = $filters{$input{'type'}}{names};
2022 for my $name (keys %$names) {
2023 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
2024 $input{$name} = $names->{$name}{$input{$name}};
2028 if (defined($filters{$input{'type'}}{defaults})) {
2029 %hsh=( image => $self->{IMG},
2031 %{$filters{$input{'type'}}{defaults}},
2034 %hsh=( image => $self->{IMG},
2039 my @cs=@{$filters{$input{'type'}}{callseq}};
2042 if (!defined($hsh{$_})) {
2043 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
2048 local $SIG{__DIE__}; # we don't want this processed by confess, etc
2049 &{$filters{$input{'type'}}{callsub}}(%hsh);
2052 chomp($self->{ERRSTR} = $@);
2058 $self->{DEBUG} && print "callseq is: @cs\n";
2059 $self->{DEBUG} && print "matching callseq is: @b\n";
2064 sub register_filter {
2066 my %hsh = ( defaults => {}, @_ );
2069 or die "register_filter() with no type\n";
2070 defined $hsh{callsub}
2071 or die "register_filter() with no callsub\n";
2072 defined $hsh{callseq}
2073 or die "register_filter() with no callseq\n";
2075 exists $filters{$hsh{type}}
2078 $filters{$hsh{type}} = \%hsh;
2083 sub scale_calculate {
2086 my %opts = ('type'=>'max', @_);
2088 # none of these should be references
2089 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2090 if (defined $opts{$name} && ref $opts{$name}) {
2091 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2096 my ($x_scale, $y_scale);
2097 my $width = $opts{width};
2098 my $height = $opts{height};
2100 defined $width or $width = $self->getwidth;
2101 defined $height or $height = $self->getheight;
2104 unless (defined $width && defined $height) {
2105 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2110 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2111 $x_scale = $opts{'xscalefactor'};
2112 $y_scale = $opts{'yscalefactor'};
2114 elsif ($opts{'xscalefactor'}) {
2115 $x_scale = $opts{'xscalefactor'};
2116 $y_scale = $opts{'scalefactor'} || $x_scale;
2118 elsif ($opts{'yscalefactor'}) {
2119 $y_scale = $opts{'yscalefactor'};
2120 $x_scale = $opts{'scalefactor'} || $y_scale;
2123 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2126 # work out the scaling
2127 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2128 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2129 $opts{ypixels} / $height );
2130 if ($opts{'type'} eq 'min') {
2131 $x_scale = $y_scale = _min($xpix,$ypix);
2133 elsif ($opts{'type'} eq 'max') {
2134 $x_scale = $y_scale = _max($xpix,$ypix);
2136 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2141 $self->_set_error('invalid value for type parameter');
2144 } elsif ($opts{xpixels}) {
2145 $x_scale = $y_scale = $opts{xpixels} / $width;
2147 elsif ($opts{ypixels}) {
2148 $x_scale = $y_scale = $opts{ypixels}/$height;
2150 elsif ($opts{constrain} && ref $opts{constrain}
2151 && $opts{constrain}->can('constrain')) {
2152 # we've been passed an Image::Math::Constrain object or something
2153 # that looks like one
2155 (undef, undef, $scalefactor)
2156 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2157 unless ($scalefactor) {
2158 $self->_set_error('constrain method failed on constrain parameter');
2161 $x_scale = $y_scale = $scalefactor;
2164 my $new_width = int($x_scale * $width + 0.5);
2165 $new_width > 0 or $new_width = 1;
2166 my $new_height = int($y_scale * $height + 0.5);
2167 $new_height > 0 or $new_height = 1;
2169 return ($x_scale, $y_scale, $new_width, $new_height);
2173 # Scale an image to requested size and return the scaled version
2177 my %opts = (qtype=>'normal' ,@_);
2178 my $img = Imager->new();
2179 my $tmp = Imager->new();
2181 unless (defined wantarray) {
2182 my @caller = caller;
2183 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2187 unless ($self->{IMG}) {
2188 $self->_set_error('empty input image');
2192 my ($x_scale, $y_scale, $new_width, $new_height) =
2193 $self->scale_calculate(%opts)
2196 if ($opts{qtype} eq 'normal') {
2197 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2198 if ( !defined($tmp->{IMG}) ) {
2199 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2202 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2203 if ( !defined($img->{IMG}) ) {
2204 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2210 elsif ($opts{'qtype'} eq 'preview') {
2211 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2212 if ( !defined($img->{IMG}) ) {
2213 $self->{ERRSTR}='unable to scale image';
2218 elsif ($opts{'qtype'} eq 'mixing') {
2219 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2220 unless ($img->{IMG}) {
2221 $self->_set_error(Imager->_error_as_msg);
2227 $self->_set_error('invalid value for qtype parameter');
2232 # Scales only along the X axis
2236 my %opts = ( scalefactor=>0.5, @_ );
2238 unless (defined wantarray) {
2239 my @caller = caller;
2240 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2244 unless ($self->{IMG}) {
2245 $self->{ERRSTR} = 'empty input image';
2249 my $img = Imager->new();
2251 my $scalefactor = $opts{scalefactor};
2253 if ($opts{pixels}) {
2254 $scalefactor = $opts{pixels} / $self->getwidth();
2257 unless ($self->{IMG}) {
2258 $self->{ERRSTR}='empty input image';
2262 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2264 if ( !defined($img->{IMG}) ) {
2265 $self->{ERRSTR} = 'unable to scale image';
2272 # Scales only along the Y axis
2276 my %opts = ( scalefactor => 0.5, @_ );
2278 unless (defined wantarray) {
2279 my @caller = caller;
2280 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2284 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2286 my $img = Imager->new();
2288 my $scalefactor = $opts{scalefactor};
2290 if ($opts{pixels}) {
2291 $scalefactor = $opts{pixels} / $self->getheight();
2294 unless ($self->{IMG}) {
2295 $self->{ERRSTR} = 'empty input image';
2298 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2300 if ( !defined($img->{IMG}) ) {
2301 $self->{ERRSTR} = 'unable to scale image';
2308 # Transform returns a spatial transformation of the input image
2309 # this moves pixels to a new location in the returned image.
2310 # NOTE - should make a utility function to check transforms for
2315 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2317 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2319 # print Dumper(\%opts);
2322 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2324 eval ("use Affix::Infix2Postfix;");
2327 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2330 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2331 {op=>'-',trans=>'Sub'},
2332 {op=>'*',trans=>'Mult'},
2333 {op=>'/',trans=>'Div'},
2334 {op=>'-','type'=>'unary',trans=>'u-'},
2336 {op=>'func','type'=>'unary'}],
2337 'grouping'=>[qw( \( \) )],
2338 'func'=>[qw( sin cos )],
2343 @xt=$I2P->translate($opts{'xexpr'});
2344 @yt=$I2P->translate($opts{'yexpr'});
2346 $numre=$I2P->{'numre'};
2349 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2350 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2351 @{$opts{'parm'}}=@pt;
2354 # print Dumper(\%opts);
2356 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2357 $self->{ERRSTR}='transform: no xopcodes given.';
2361 @op=@{$opts{'xopcodes'}};
2363 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2364 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2367 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2373 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2374 $self->{ERRSTR}='transform: no yopcodes given.';
2378 @op=@{$opts{'yopcodes'}};
2380 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2381 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2384 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2389 if ( !exists $opts{'parm'}) {
2390 $self->{ERRSTR}='transform: no parameter arg given.';
2394 # print Dumper(\@ropx);
2395 # print Dumper(\@ropy);
2396 # print Dumper(\@ropy);
2398 my $img = Imager->new();
2399 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2400 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2406 my ($opts, @imgs) = @_;
2408 require "Imager/Expr.pm";
2410 $opts->{variables} = [ qw(x y) ];
2411 my ($width, $height) = @{$opts}{qw(width height)};
2413 $width ||= $imgs[0]->getwidth();
2414 $height ||= $imgs[0]->getheight();
2416 for my $img (@imgs) {
2417 $opts->{constants}{"w$img_num"} = $img->getwidth();
2418 $opts->{constants}{"h$img_num"} = $img->getheight();
2419 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2420 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2425 $opts->{constants}{w} = $width;
2426 $opts->{constants}{cx} = $width/2;
2429 $Imager::ERRSTR = "No width supplied";
2433 $opts->{constants}{h} = $height;
2434 $opts->{constants}{cy} = $height/2;
2437 $Imager::ERRSTR = "No height supplied";
2440 my $code = Imager::Expr->new($opts);
2442 $Imager::ERRSTR = Imager::Expr::error();
2445 my $channels = $opts->{channels} || 3;
2446 unless ($channels >= 1 && $channels <= 4) {
2447 return Imager->_set_error("channels must be an integer between 1 and 4");
2450 my $img = Imager->new();
2451 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2452 $channels, $code->code(),
2453 $code->nregs(), $code->cregs(),
2454 [ map { $_->{IMG} } @imgs ]);
2455 if (!defined $img->{IMG}) {
2456 $Imager::ERRSTR = Imager->_error_as_msg();
2467 unless ($self->{IMG}) {
2468 $self->{ERRSTR}='empty input image';
2471 unless ($opts{src} && $opts{src}->{IMG}) {
2472 $self->{ERRSTR}='empty input image for src';
2476 %opts = (src_minx => 0,
2478 src_maxx => $opts{src}->getwidth(),
2479 src_maxy => $opts{src}->getheight(),
2483 defined $tx or $tx = $opts{left};
2484 defined $tx or $tx = 0;
2487 defined $ty or $ty = $opts{top};
2488 defined $ty or $ty = 0;
2490 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2491 $opts{src_minx}, $opts{src_miny},
2492 $opts{src_maxx}, $opts{src_maxy})) {
2493 $self->_set_error($self->_error_as_msg());
2510 unless ($self->{IMG}) {
2511 $self->_set_error("compose: empty input image");
2515 unless ($opts{src}) {
2516 $self->_set_error("compose: src parameter missing");
2520 unless ($opts{src}{IMG}) {
2521 $self->_set_error("compose: src parameter empty image");
2524 my $src = $opts{src};
2526 my $left = $opts{left};
2527 defined $left or $left = $opts{tx};
2528 defined $left or $left = 0;
2530 my $top = $opts{top};
2531 defined $top or $top = $opts{ty};
2532 defined $top or $top = 0;
2534 my $src_left = $opts{src_left};
2535 defined $src_left or $src_left = $opts{src_minx};
2536 defined $src_left or $src_left = 0;
2538 my $src_top = $opts{src_top};
2539 defined $src_top or $src_top = $opts{src_miny};
2540 defined $src_top or $src_top = 0;
2542 my $width = $opts{width};
2543 if (!defined $width && defined $opts{src_maxx}) {
2544 $width = $opts{src_maxx} - $src_left;
2546 defined $width or $width = $src->getwidth() - $src_left;
2548 my $height = $opts{height};
2549 if (!defined $height && defined $opts{src_maxy}) {
2550 $height = $opts{src_maxy} - $src_top;
2552 defined $height or $height = $src->getheight() - $src_top;
2554 my $combine = $self->_combine($opts{combine}, 'normal');
2557 unless ($opts{mask}{IMG}) {
2558 $self->_set_error("compose: mask parameter empty image");
2562 my $mask_left = $opts{mask_left};
2563 defined $mask_left or $mask_left = $opts{mask_minx};
2564 defined $mask_left or $mask_left = 0;
2566 my $mask_top = $opts{mask_top};
2567 defined $mask_top or $mask_top = $opts{mask_miny};
2568 defined $mask_top or $mask_top = 0;
2570 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2571 $left, $top, $src_left, $src_top,
2572 $mask_left, $mask_top, $width, $height,
2573 $combine, $opts{opacity})) {
2574 $self->_set_error(Imager->_error_as_msg);
2579 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2580 $width, $height, $combine, $opts{opacity})) {
2581 $self->_set_error(Imager->_error_as_msg);
2592 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2594 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2595 $dir = $xlate{$opts{'dir'}};
2596 return $self if i_flipxy($self->{IMG}, $dir);
2604 unless (defined wantarray) {
2605 my @caller = caller;
2606 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2610 if (defined $opts{right}) {
2611 my $degrees = $opts{right};
2613 $degrees += 360 * int(((-$degrees)+360)/360);
2615 $degrees = $degrees % 360;
2616 if ($degrees == 0) {
2617 return $self->copy();
2619 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2620 my $result = Imager->new();
2621 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2625 $self->{ERRSTR} = $self->_error_as_msg();
2630 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2634 elsif (defined $opts{radians} || defined $opts{degrees}) {
2635 my $amount = $opts{radians} || $opts{degrees} * 3.14159265358979 / 180;
2637 my $back = $opts{back};
2638 my $result = Imager->new;
2640 $back = _color($back);
2642 $self->_set_error(Imager->errstr);
2646 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2649 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2651 if ($result->{IMG}) {
2655 $self->{ERRSTR} = $self->_error_as_msg();
2660 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2665 sub matrix_transform {
2669 unless (defined wantarray) {
2670 my @caller = caller;
2671 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2675 if ($opts{matrix}) {
2676 my $xsize = $opts{xsize} || $self->getwidth;
2677 my $ysize = $opts{ysize} || $self->getheight;
2679 my $result = Imager->new;
2681 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2682 $opts{matrix}, $opts{back})
2686 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2694 $self->{ERRSTR} = "matrix parameter required";
2700 *yatf = \&matrix_transform;
2702 # These two are supported for legacy code only
2705 return Imager::Color->new(@_);
2709 return Imager::Color::set(@_);
2712 # Draws a box between the specified corner points.
2715 my $raw = $self->{IMG};
2718 $self->{ERRSTR}='empty input image';
2724 my ($xmin, $ymin, $xmax, $ymax);
2725 if (exists $opts{'box'}) {
2726 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2727 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2728 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2729 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2732 defined($xmin = $opts{xmin}) or $xmin = 0;
2733 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2734 defined($ymin = $opts{ymin}) or $ymin = 0;
2735 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2738 if ($opts{filled}) {
2739 my $color = $opts{'color'};
2741 if (defined $color) {
2742 unless (_is_color_object($color)) {
2743 $color = _color($color);
2745 $self->{ERRSTR} = $Imager::ERRSTR;
2751 $color = i_color_new(255,255,255,255);
2754 if ($color->isa("Imager::Color")) {
2755 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2758 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2761 elsif ($opts{fill}) {
2762 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2763 # assume it's a hash ref
2764 require 'Imager/Fill.pm';
2765 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2766 $self->{ERRSTR} = $Imager::ERRSTR;
2770 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2773 my $color = $opts{'color'};
2774 if (defined $color) {
2775 unless (_is_color_object($color)) {
2776 $color = _color($color);
2778 $self->{ERRSTR} = $Imager::ERRSTR;
2784 $color = i_color_new(255, 255, 255, 255);
2787 $self->{ERRSTR} = $Imager::ERRSTR;
2790 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2798 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2799 my $dflcl= [ 255, 255, 255, 255];
2804 'r'=>_min($self->getwidth(),$self->getheight())/3,
2805 'x'=>$self->getwidth()/2,
2806 'y'=>$self->getheight()/2,
2813 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2814 # assume it's a hash ref
2815 require 'Imager/Fill.pm';
2816 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2817 $self->{ERRSTR} = $Imager::ERRSTR;
2821 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2822 $opts{'d2'}, $opts{fill}{fill});
2824 elsif ($opts{filled}) {
2825 my $color = _color($opts{'color'});
2827 $self->{ERRSTR} = $Imager::ERRSTR;
2830 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2831 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2835 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2836 $opts{'d1'}, $opts{'d2'}, $color);
2840 my $color = _color($opts{'color'});
2841 if ($opts{d2} - $opts{d1} >= 360) {
2842 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
2845 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
2851 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2852 # assume it's a hash ref
2853 require 'Imager/Fill.pm';
2854 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2855 $self->{ERRSTR} = $Imager::ERRSTR;
2859 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2860 $opts{'d2'}, $opts{fill}{fill});
2863 my $color = _color($opts{'color'});
2865 $self->{ERRSTR} = $Imager::ERRSTR;
2868 if ($opts{filled}) {
2869 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2870 $opts{'d1'}, $opts{'d2'}, $color);
2873 if ($opts{d1} == 0 && $opts{d2} == 361) {
2874 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
2877 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
2883 $self->_set_error($self->_error_as_msg);
2890 # Draws a line from one point to the other
2891 # the endpoint is set if the endp parameter is set which it is by default.
2892 # to turn of the endpoint being set use endp=>0 when calling line.
2896 my $dflcl=i_color_new(0,0,0,0);
2897 my %opts=(color=>$dflcl,
2900 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2902 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
2903 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
2905 my $color = _color($opts{'color'});
2907 $self->{ERRSTR} = $Imager::ERRSTR;
2911 $opts{antialias} = $opts{aa} if defined $opts{aa};
2912 if ($opts{antialias}) {
2913 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2914 $color, $opts{endp});
2916 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2917 $color, $opts{endp});
2922 # Draws a line between an ordered set of points - It more or less just transforms this
2923 # into a list of lines.
2927 my ($pt,$ls,@points);
2928 my $dflcl=i_color_new(0,0,0,0);
2929 my %opts=(color=>$dflcl,@_);
2931 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2933 if (exists($opts{points})) { @points=@{$opts{points}}; }
2934 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
2935 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
2938 # print Dumper(\@points);
2940 my $color = _color($opts{'color'});
2942 $self->{ERRSTR} = $Imager::ERRSTR;
2945 $opts{antialias} = $opts{aa} if defined $opts{aa};
2946 if ($opts{antialias}) {
2949 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
2956 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
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})) {
2973 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
2974 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
2977 if (!exists $opts{'x'} or !exists $opts{'y'}) {
2978 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
2981 if ($opts{'fill'}) {
2982 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
2983 # assume it's a hash ref
2984 require 'Imager/Fill.pm';
2985 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
2986 $self->{ERRSTR} = $Imager::ERRSTR;
2990 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
2991 $opts{'fill'}{'fill'});
2994 my $color = _color($opts{'color'});
2996 $self->{ERRSTR} = $Imager::ERRSTR;
2999 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3006 # this the multipoint bezier curve
3007 # this is here more for testing that actual usage since
3008 # this is not a good algorithm. Usually the curve would be
3009 # broken into smaller segments and each done individually.
3013 my ($pt,$ls,@points);
3014 my $dflcl=i_color_new(0,0,0,0);
3015 my %opts=(color=>$dflcl,@_);
3017 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3019 if (exists $opts{points}) {
3020 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
3021 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
3024 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
3025 $self->{ERRSTR}='Missing or invalid points.';
3029 my $color = _color($opts{'color'});
3031 $self->{ERRSTR} = $Imager::ERRSTR;
3034 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
3040 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
3043 unless (exists $opts{'x'} && exists $opts{'y'}) {
3044 $self->{ERRSTR} = "missing seed x and y parameters";
3048 if ($opts{border}) {
3049 my $border = _color($opts{border});
3051 $self->_set_error($Imager::ERRSTR);
3055 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3056 # assume it's a hash ref
3057 require Imager::Fill;
3058 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3059 $self->{ERRSTR} = $Imager::ERRSTR;
3063 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3064 $opts{fill}{fill}, $border);
3067 my $color = _color($opts{'color'});
3069 $self->{ERRSTR} = $Imager::ERRSTR;
3072 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3079 $self->{ERRSTR} = $self->_error_as_msg();
3085 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3086 # assume it's a hash ref
3087 require 'Imager/Fill.pm';
3088 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3089 $self->{ERRSTR} = $Imager::ERRSTR;
3093 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3096 my $color = _color($opts{'color'});
3098 $self->{ERRSTR} = $Imager::ERRSTR;
3101 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3107 $self->{ERRSTR} = $self->_error_as_msg();
3114 my ($self, %opts) = @_;
3116 $self->_valid_image("setpixel")
3119 my $color = $opts{color};
3120 unless (defined $color) {
3121 $color = $self->{fg};
3122 defined $color or $color = NC(255, 255, 255);
3125 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3126 unless ($color = _color($color, 'setpixel')) {
3127 $self->_set_error("setpixel: " . Imager->errstr);
3132 unless (exists $opts{'x'} && exists $opts{'y'}) {
3133 $self->_set_error('setpixel: missing x or y parameter');
3139 if (ref $x || ref $y) {
3140 $x = ref $x ? $x : [ $x ];
3141 $y = ref $y ? $y : [ $y ];
3143 $self->_set_error("setpixel: x is a reference to an empty array");
3147 $self->_set_error("setpixel: y is a reference to an empty array");
3151 # make both the same length, replicating the last element
3153 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3156 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3160 if ($color->isa('Imager::Color')) {
3161 for my $i (0..$#$x) {
3162 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3167 for my $i (0..$#$x) {
3168 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3176 if ($color->isa('Imager::Color')) {
3177 i_ppix($self->{IMG}, $x, $y, $color)
3181 i_ppixf($self->{IMG}, $x, $y, $color)
3192 my %opts = ( "type"=>'8bit', @_);
3194 $self->_valid_image("getpixel")
3197 unless (exists $opts{'x'} && exists $opts{'y'}) {
3198 $self->_set_error('getpixel: missing x or y parameter');
3204 my $type = $opts{'type'};
3205 if (ref $x || ref $y) {
3206 $x = ref $x ? $x : [ $x ];
3207 $y = ref $y ? $y : [ $y ];
3209 $self->_set_error("getpixel: x is a reference to an empty array");
3213 $self->_set_error("getpixel: y is a reference to an empty array");
3217 # make both the same length, replicating the last element
3219 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3222 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3226 if ($type eq '8bit') {
3227 for my $i (0..$#$x) {
3228 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3231 elsif ($type eq 'float' || $type eq 'double') {
3232 for my $i (0..$#$x) {
3233 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3237 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3240 return wantarray ? @result : \@result;
3243 if ($type eq '8bit') {
3244 return i_get_pixel($self->{IMG}, $x, $y);
3246 elsif ($type eq 'float' || $type eq 'double') {
3247 return i_gpixf($self->{IMG}, $x, $y);
3250 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3258 my %opts = ( type => '8bit', x=>0, @_);
3260 $self->_valid_image or return;
3262 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3264 unless (defined $opts{'y'}) {
3265 $self->_set_error("missing y parameter");
3269 if ($opts{type} eq '8bit') {
3270 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3273 elsif ($opts{type} eq 'float') {
3274 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3277 elsif ($opts{type} eq 'index') {
3278 unless (i_img_type($self->{IMG})) {
3279 $self->_set_error("type => index only valid on paletted images");
3282 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3286 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3293 my %opts = ( x=>0, @_);
3295 $self->_valid_image or return;
3297 unless (defined $opts{'y'}) {
3298 $self->_set_error("missing y parameter");
3303 if (ref $opts{pixels} && @{$opts{pixels}}) {
3304 # try to guess the type
3305 if ($opts{pixels}[0]->isa('Imager::Color')) {
3306 $opts{type} = '8bit';
3308 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3309 $opts{type} = 'float';
3312 $self->_set_error("missing type parameter and could not guess from pixels");
3318 $opts{type} = '8bit';
3322 if ($opts{type} eq '8bit') {
3323 if (ref $opts{pixels}) {
3324 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3327 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3330 elsif ($opts{type} eq 'float') {
3331 if (ref $opts{pixels}) {
3332 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3335 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3338 elsif ($opts{type} eq 'index') {
3339 if (ref $opts{pixels}) {
3340 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3343 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3347 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3354 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3356 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3358 unless (defined $opts{'y'}) {
3359 $self->_set_error("missing y parameter");
3363 if ($opts{target}) {
3364 my $target = $opts{target};
3365 my $offset = $opts{offset};
3366 if ($opts{type} eq '8bit') {
3367 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3368 $opts{y}, $opts{channels})
3370 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3371 return scalar(@samples);
3373 elsif ($opts{type} eq 'float') {
3374 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3375 $opts{y}, $opts{channels});
3376 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3377 return scalar(@samples);
3379 elsif ($opts{type} =~ /^(\d+)bit$/) {
3383 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3384 $opts{y}, $bits, $target,
3385 $offset, $opts{channels});
3386 unless (defined $count) {
3387 $self->_set_error(Imager->_error_as_msg);
3394 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3399 if ($opts{type} eq '8bit') {
3400 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3401 $opts{y}, $opts{channels});
3403 elsif ($opts{type} eq 'float') {
3404 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3405 $opts{y}, $opts{channels});
3407 elsif ($opts{type} =~ /^(\d+)bit$/) {
3411 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3412 $opts{y}, $bits, \@data, 0, $opts{channels})
3417 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3425 my %opts = ( x => 0, offset => 0, @_ );
3427 unless ($self->{IMG}) {
3428 $self->_set_error('setsamples: empty input image');
3432 my $data = $opts{data};
3433 unless(defined $data) {
3434 $self->_set_error('setsamples: data parameter missing');
3438 my $type = $opts{type};
3439 defined $type or $type = '8bit';
3441 my $width = defined $opts{width} ? $opts{width}
3442 : $self->getwidth() - $opts{x};
3445 if ($type eq '8bit') {
3446 $count = i_psamp($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3447 $data, $opts{offset}, $width);
3449 elsif ($type eq 'float') {
3450 $count = i_psampf($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3451 $data, $opts{offset}, $width);
3453 elsif ($type =~ /^([0-9]+)bit$/) {
3456 unless (ref $data) {
3457 $self->_set_error("setsamples: data must be an array ref for type not 8bit or float");
3461 $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3462 $opts{channels}, $data, $opts{offset},
3466 $self->_set_error('setsamples: type parameter invalid');
3470 unless (defined $count) {
3471 $self->_set_error(Imager->_error_as_msg);
3478 # make an identity matrix of the given size
3482 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3483 for my $c (0 .. ($size-1)) {
3484 $matrix->[$c][$c] = 1;
3489 # general function to convert an image
3491 my ($self, %opts) = @_;
3494 unless (defined wantarray) {
3495 my @caller = caller;
3496 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3500 # the user can either specify a matrix or preset
3501 # the matrix overrides the preset
3502 if (!exists($opts{matrix})) {
3503 unless (exists($opts{preset})) {
3504 $self->{ERRSTR} = "convert() needs a matrix or preset";
3508 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3509 # convert to greyscale, keeping the alpha channel if any
3510 if ($self->getchannels == 3) {
3511 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3513 elsif ($self->getchannels == 4) {
3514 # preserve the alpha channel
3515 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3520 $matrix = _identity($self->getchannels);
3523 elsif ($opts{preset} eq 'noalpha') {
3524 # strip the alpha channel
3525 if ($self->getchannels == 2 or $self->getchannels == 4) {
3526 $matrix = _identity($self->getchannels);
3527 pop(@$matrix); # lose the alpha entry
3530 $matrix = _identity($self->getchannels);
3533 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3535 $matrix = [ [ 1 ] ];
3537 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3538 $matrix = [ [ 0, 1 ] ];
3540 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3541 $matrix = [ [ 0, 0, 1 ] ];
3543 elsif ($opts{preset} eq 'alpha') {
3544 if ($self->getchannels == 2 or $self->getchannels == 4) {
3545 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3548 # the alpha is just 1 <shrug>
3549 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3552 elsif ($opts{preset} eq 'rgb') {
3553 if ($self->getchannels == 1) {
3554 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3556 elsif ($self->getchannels == 2) {
3557 # preserve the alpha channel
3558 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3561 $matrix = _identity($self->getchannels);
3564 elsif ($opts{preset} eq 'addalpha') {
3565 if ($self->getchannels == 1) {
3566 $matrix = _identity(2);
3568 elsif ($self->getchannels == 3) {
3569 $matrix = _identity(4);
3572 $matrix = _identity($self->getchannels);
3576 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3582 $matrix = $opts{matrix};
3585 my $new = Imager->new;
3586 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3587 unless ($new->{IMG}) {
3588 # most likely a bad matrix
3589 $self->{ERRSTR} = _error_as_msg();
3595 # combine channels from multiple input images, a class method
3597 my ($class, %opts) = @_;
3599 my $src = delete $opts{src};
3601 $class->_set_error("src parameter missing");
3606 for my $img (@$src) {
3607 unless (eval { $img->isa("Imager") }) {
3608 $class->_set_error("src must contain image objects");
3611 unless ($img->{IMG}) {
3612 $class->_set_error("empty input image");
3615 push @imgs, $img->{IMG};
3618 if (my $channels = delete $opts{channels}) {
3619 $result = i_combine(\@imgs, $channels);
3622 $result = i_combine(\@imgs);
3625 $class->_set_error($class->_error_as_msg);
3629 my $img = $class->new;
3630 $img->{IMG} = $result;
3636 # general function to map an image through lookup tables
3639 my ($self, %opts) = @_;
3640 my @chlist = qw( red green blue alpha );
3642 if (!exists($opts{'maps'})) {
3643 # make maps from channel maps
3645 for $chnum (0..$#chlist) {
3646 if (exists $opts{$chlist[$chnum]}) {
3647 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3648 } elsif (exists $opts{'all'}) {
3649 $opts{'maps'}[$chnum] = $opts{'all'};
3653 if ($opts{'maps'} and $self->{IMG}) {
3654 i_map($self->{IMG}, $opts{'maps'} );
3660 my ($self, %opts) = @_;
3662 defined $opts{mindist} or $opts{mindist} = 0;
3664 defined $opts{other}
3665 or return $self->_set_error("No 'other' parameter supplied");
3666 defined $opts{other}{IMG}
3667 or return $self->_set_error("No image data in 'other' image");
3670 or return $self->_set_error("No image data");
3672 my $result = Imager->new;
3673 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3675 or return $self->_set_error($self->_error_as_msg());
3680 # destructive border - image is shrunk by one pixel all around
3683 my ($self,%opts)=@_;
3684 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3685 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3689 # Get the width of an image
3694 if (my $raw = $self->{IMG}) {
3695 return i_img_get_width($raw);
3698 $self->{ERRSTR} = 'image is empty'; return undef;
3702 # Get the height of an image
3707 if (my $raw = $self->{IMG}) {
3708 return i_img_get_height($raw);
3711 $self->{ERRSTR} = 'image is empty'; return undef;
3715 # Get number of channels in an image
3719 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3720 return i_img_getchannels($self->{IMG});
3727 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3728 return i_img_getmask($self->{IMG});
3736 if (!defined($self->{IMG})) {
3737 $self->{ERRSTR} = 'image is empty';
3740 unless (defined $opts{mask}) {
3741 $self->_set_error("mask parameter required");
3744 i_img_setmask( $self->{IMG} , $opts{mask} );
3749 # Get number of colors in an image
3753 my %opts=('maxcolors'=>2**30,@_);
3754 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
3755 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
3756 return ($rc==-1? undef : $rc);
3759 # Returns a reference to a hash. The keys are colour named (packed) and the
3760 # values are the number of pixels in this colour.
3761 sub getcolorusagehash {
3764 my %opts = ( maxcolors => 2**30, @_ );
3765 my $max_colors = $opts{maxcolors};
3766 unless (defined $max_colors && $max_colors > 0) {
3767 $self->_set_error('maxcolors must be a positive integer');
3771 unless (defined $self->{IMG}) {
3772 $self->_set_error('empty input image');
3776 my $channels= $self->getchannels;
3777 # We don't want to look at the alpha channel, because some gifs using it
3778 # doesn't define it for every colour (but only for some)
3779 $channels -= 1 if $channels == 2 or $channels == 4;
3781 my $height = $self->getheight;
3782 for my $y (0 .. $height - 1) {
3783 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
3784 while (length $colors) {
3785 $color_use{ substr($colors, 0, $channels, '') }++;
3787 keys %color_use > $max_colors
3793 # This will return a ordered array of the colour usage. Kind of the sorted
3794 # version of the values of the hash returned by getcolorusagehash.
3795 # You might want to add safety checks and change the names, etc...
3799 my %opts = ( maxcolors => 2**30, @_ );
3800 my $max_colors = $opts{maxcolors};
3801 unless (defined $max_colors && $max_colors > 0) {
3802 $self->_set_error('maxcolors must be a positive integer');
3806 unless (defined $self->{IMG}) {
3807 $self->_set_error('empty input image');
3811 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
3814 # draw string to an image
3818 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3820 my %input=('x'=>0, 'y'=>0, @_);
3821 defined($input{string}) or $input{string} = $input{text};
3823 unless(defined $input{string}) {
3824 $self->{ERRSTR}="missing required parameter 'string'";
3828 unless($input{font}) {
3829 $self->{ERRSTR}="missing required parameter 'font'";
3833 unless ($input{font}->draw(image=>$self, %input)) {
3845 unless ($self->{IMG}) {
3846 $self->{ERRSTR}='empty input image';
3855 my %input=('x'=>0, 'y'=>0, @_);
3856 defined $input{string}
3857 or $input{string} = $input{text};
3859 unless(exists $input{string}) {
3860 $self->_set_error("missing required parameter 'string'");
3864 unless($input{font}) {
3865 $self->_set_error("missing required parameter 'font'");
3870 unless (@result = $input{font}->align(image=>$img, %input)) {
3874 return wantarray ? @result : $result[0];
3877 my @file_limit_names = qw/width height bytes/;
3879 sub set_file_limits {
3886 @values{@file_limit_names} = (0) x @file_limit_names;
3889 @values{@file_limit_names} = i_get_image_file_limits();
3892 for my $key (keys %values) {
3893 defined $opts{$key} and $values{$key} = $opts{$key};
3896 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
3899 sub get_file_limits {
3900 i_get_image_file_limits();
3903 # Shortcuts that can be exported
3905 sub newcolor { Imager::Color->new(@_); }
3906 sub newfont { Imager::Font->new(@_); }
3908 require Imager::Color::Float;
3909 return Imager::Color::Float->new(@_);
3912 *NC=*newcolour=*newcolor;
3919 #### Utility routines
3922 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
3926 my ($self, $msg) = @_;
3929 $self->{ERRSTR} = $msg;
3937 # Default guess for the type of an image from extension
3939 my @simple_types = qw(png tga gif raw ico cur xpm mng jng ilbm pcx psd eps);
3943 ( map { $_ => $_ } @simple_types ),
3949 pnm => "pnm", # technically wrong, but historically it works in Imager
3962 sub def_guess_type {
3965 my ($ext) = $name =~ /\.([^.]+)$/
3968 my $type = $ext_types{$ext}
3975 return @combine_types;
3978 # get the minimum of a list
3982 for(@_) { if ($_<$mx) { $mx=$_; }}
3986 # get the maximum of a list
3990 for(@_) { if ($_>$mx) { $mx=$_; }}
3994 # string stuff for iptc headers
3998 $str = substr($str,3);
3999 $str =~ s/[\n\r]//g;
4006 # A little hack to parse iptc headers.
4011 my($caption,$photogr,$headln,$credit);
4013 my $str=$self->{IPTCRAW};
4018 @ar=split(/8BIM/,$str);
4023 @sar=split(/\034\002/);
4024 foreach $item (@sar) {
4025 if ($item =~ m/^x/) {
4026 $caption = _clean($item);
4029 if ($item =~ m/^P/) {
4030 $photogr = _clean($item);
4033 if ($item =~ m/^i/) {
4034 $headln = _clean($item);
4037 if ($item =~ m/^n/) {
4038 $credit = _clean($item);
4044 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
4051 or die "Only C language supported";
4053 require Imager::ExtUtils;
4054 return Imager::ExtUtils->inline_config;
4057 # threads shouldn't try to close raw Imager objects
4058 sub Imager::ImgRaw::CLONE_SKIP { 1 }
4061 # this serves two purposes:
4062 # - a class method to load the file support modules included with Imager
4063 # (or were included, once the library dependent modules are split out)
4064 # - something for Module::ScanDeps to analyze
4065 # https://rt.cpan.org/Ticket/Display.html?id=6566
4067 eval { require Imager::File::GIF };
4068 eval { require Imager::File::JPEG };
4069 eval { require Imager::File::PNG };
4070 eval { require Imager::File::SGI };
4071 eval { require Imager::File::TIFF };
4072 eval { require Imager::File::ICO };
4073 eval { require Imager::Font::W32 };
4074 eval { require Imager::Font::FT2 };
4075 eval { require Imager::Font::T1 };
4078 # backward compatibility for %formats
4079 package Imager::FORMATS;
4081 use constant IX_FORMATS => 0;
4082 use constant IX_LIST => 1;
4083 use constant IX_INDEX => 2;
4084 use constant IX_CLASSES => 3;
4087 my ($class, $formats, $classes) = @_;
4089 return bless [ $formats, [ ], 0, $classes ], $class;
4093 my ($self, $key) = @_;
4095 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
4098 my $loaded = Imager::_load_file($file, \$error);
4103 if ($error =~ /^Can't locate /) {
4104 $error = "Can't locate $file";
4106 $reader_load_errors{$key} = $writer_load_errors{$key} = $error;
4109 $self->[IX_FORMATS]{$key} = $value;
4115 my ($self, $key) = @_;
4117 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
4119 $self->[IX_CLASSES]{$key} or return undef;
4121 return $self->_check($key);
4125 die "%Imager::formats is not user monifiable";
4129 die "%Imager::formats is not user monifiable";
4133 die "%Imager::formats is not user monifiable";
4137 my ($self, $key) = @_;
4139 if (exists $self->[IX_FORMATS]{$key}) {
4140 my $value = $self->[IX_FORMATS]{$key}
4145 $self->_check($key) or return 1==0;
4153 unless (@{$self->[IX_LIST]}) {
4155 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4156 keys %{$self->[IX_FORMATS]};
4158 for my $key (keys %{$self->[IX_CLASSES]}) {
4159 $self->[IX_FORMATS]{$key} and next;
4161 and push @{$self->[IX_LIST]}, $key;
4165 @{$self->[IX_LIST]} or return;
4166 $self->[IX_INDEX] = 1;
4167 return $self->[IX_LIST][0];
4173 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4176 return $self->[IX_LIST][$self->[IX_INDEX]++];
4182 return scalar @{$self->[IX_LIST]};
4187 # Below is the stub of documentation for your module. You better edit it!
4191 Imager - Perl extension for Generating 24 bit Images
4201 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4206 # see Imager::Files for information on the read() method
4207 my $img = Imager->new(file=>$file)
4208 or die Imager->errstr();
4210 $file =~ s/\.[^.]*$//;
4212 # Create smaller version
4213 # documented in Imager::Transformations
4214 my $thumb = $img->scale(scalefactor=>.3);
4216 # Autostretch individual channels
4217 $thumb->filter(type=>'autolevels');
4219 # try to save in one of these formats
4222 for $format ( qw( png gif jpeg tiff ppm ) ) {
4223 # Check if given format is supported
4224 if ($Imager::formats{$format}) {
4225 $file.="_low.$format";
4226 print "Storing image as: $file\n";
4227 # documented in Imager::Files
4228 $thumb->write(file=>$file) or
4236 Imager is a module for creating and altering images. It can read and
4237 write various image formats, draw primitive shapes like lines,and
4238 polygons, blend multiple images together in various ways, scale, crop,
4239 render text and more.
4241 =head2 Overview of documentation
4247 Imager - This document - Synopsis, Example, Table of Contents and
4252 L<Imager::Tutorial> - a brief introduction to Imager.
4256 L<Imager::Cookbook> - how to do various things with Imager.
4260 L<Imager::ImageTypes> - Basics of constructing image objects with
4261 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4262 8/16/double bits/channel, color maps, channel masks, image tags, color
4263 quantization. Also discusses basic image information methods.
4267 L<Imager::Files> - IO interaction, reading/writing images, format
4272 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4277 L<Imager::Color> - Color specification.
4281 L<Imager::Fill> - Fill pattern specification.
4285 L<Imager::Font> - General font rendering, bounding boxes and font
4290 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4291 blending, pasting, convert and map.
4295 L<Imager::Engines> - Programmable transformations through
4296 C<transform()>, C<transform2()> and C<matrix_transform()>.
4300 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4305 L<Imager::Expr> - Expressions for evaluation engine used by
4310 L<Imager::Matrix2d> - Helper class for affine transformations.
4314 L<Imager::Fountain> - Helper for making gradient profiles.
4318 L<Imager::API> - using Imager's C API
4322 L<Imager::APIRef> - API function reference
4326 L<Imager::Inline> - using Imager's C API from Inline::C
4330 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4334 =head2 Basic Overview
4336 An Image object is created with C<$img = Imager-E<gt>new()>.
4339 $img=Imager->new(); # create empty image
4340 $img->read(file=>'lena.png',type=>'png') or # read image from file
4341 die $img->errstr(); # give an explanation
4342 # if something failed
4344 or if you want to create an empty image:
4346 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4348 This example creates a completely black image of width 400 and height
4351 =head1 ERROR HANDLING
4353 In general a method will return false when it fails, if it does use
4354 the C<errstr()> method to find out why:
4360 Returns the last error message in that context.
4362 If the last error you received was from calling an object method, such
4363 as read, call errstr() as an object method to find out why:
4365 my $image = Imager->new;
4366 $image->read(file => 'somefile.gif')
4367 or die $image->errstr;
4369 If it was a class method then call errstr() as a class method:
4371 my @imgs = Imager->read_multi(file => 'somefile.gif')
4372 or die Imager->errstr;
4374 Note that in some cases object methods are implemented in terms of
4375 class methods so a failing object method may set both.
4379 The C<Imager-E<gt>new> method is described in detail in
4380 L<Imager::ImageTypes>.
4384 Where to find information on methods for Imager class objects.
4386 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4389 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4391 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4394 arc() - L<Imager::Draw/arc()> - draw a filled arc
4396 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4399 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4401 circle() - L<Imager::Draw/circle()> - draw a filled circle
4403 close_log() - L<Imager::ImageTypes/close_log()> - close the Imager
4406 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4407 colors in an image's palette (paletted images only)
4409 combine() - L<Imager::Transformations/combine()> - combine channels
4410 from one or more images.
4412 combines() - L<Imager::Draw/combines()> - return a list of the
4413 different combine type keywords
4415 compose() - L<Imager::Transformations/compose()> - compose one image
4418 convert() - L<Imager::Transformations/convert()> - transform the color
4421 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4424 crop() - L<Imager::Transformations/crop()> - extract part of an image
4426 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4427 used to guess the output file format based on the output file name
4429 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4431 difference() - L<Imager::Filters/difference()> - produce a difference
4432 images from two input images.
4434 errstr() - L</errstr()> - the error from the last failed operation.
4436 filter() - L<Imager::Filters/filter()> - image filtering
4438 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4439 palette, if it has one
4441 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4444 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4447 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4448 samples per pixel for an image
4450 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4451 different colors used by an image (works for direct color images)
4453 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4454 palette, if it has one
4456 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4458 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4460 get_file_limits() - L<Imager::Files/get_file_limits()>
4462 getheight() - L<Imager::ImageTypes/getheight()> - height of the image in
4465 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4467 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4470 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4471 row or partial row of pixels.
4473 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4474 row or partial row of pixels.
4476 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4479 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4482 init() - L<Imager::ImageTypes/init()>
4484 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4485 image write functions should write the image in their bilevel (blank
4486 and white, no gray levels) format
4488 is_logging() L<Imager::ImageTypes/is_logging()> - test if the debug
4491 line() - L<Imager::Draw/line()> - draw an interval
4493 load_plugin() - L<Imager::Filters/load_plugin()>
4495 log() - L<Imager::ImageTypes/log()> - send a message to the debugging
4498 make_palette() - L<Imager::ImageTypes/make_palette()> - produce a
4499 color palette from one or more input images.
4501 map() - L<Imager::Transformations/map()> - remap color
4504 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4506 matrix_transform() - L<Imager::Engines/matrix_transform()>
4508 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4510 NC() - L<Imager::Handy/NC()>
4512 NCF() - L<Imager::Handy/NCF()>
4514 new() - L<Imager::ImageTypes/new()>
4516 newcolor() - L<Imager::Handy/newcolor()>
4518 newcolour() - L<Imager::Handy/newcolour()>
4520 newfont() - L<Imager::Handy/newfont()>
4522 NF() - L<Imager::Handy/NF()>
4524 open() - L<Imager::Files/read()> - an alias for read()
4526 open_log() - L<Imager::ImageTypes/open_log()> - open the debug log.
4530 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4533 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4536 polygon() - L<Imager::Draw/polygon()>
4538 polyline() - L<Imager::Draw/polyline()>
4540 preload() - L<Imager::Files/preload()>
4542 read() - L<Imager::Files/read()> - read a single image from an image file
4544 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
4547 read_types() - L<Imager::Files/read_types()> - list image types Imager
4550 register_filter() - L<Imager::Filters/register_filter()>
4552 register_reader() - L<Imager::Files/register_reader()>
4554 register_writer() - L<Imager::Files/register_writer()>
4556 rotate() - L<Imager::Transformations/rotate()>
4558 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
4559 onto an image and use the alpha channel
4561 scale() - L<Imager::Transformations/scale()>
4563 scale_calculate() - L<Imager::Transformations/scale_calculate()>
4565 scaleX() - L<Imager::Transformations/scaleX()>
4567 scaleY() - L<Imager::Transformations/scaleY()>
4569 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
4572 set_file_limits() - L<Imager::Files/set_file_limits()>
4574 setmask() - L<Imager::ImageTypes/setmask()>
4576 setpixel() - L<Imager::Draw/setpixel()>
4578 setsamples() - L<Imager::Draw/setsamples()>
4580 setscanline() - L<Imager::Draw/setscanline()>
4582 settag() - L<Imager::ImageTypes/settag()>
4584 string() - L<Imager::Draw/string()> - draw text on an image
4586 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
4588 to_paletted() - L<Imager::ImageTypes/to_paletted()>
4590 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
4592 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
4594 to_rgb_double() - L<Imager::ImageTypes/to_rgb_double()> - convert to
4595 double per sample image.
4597 transform() - L<Imager::Engines/"transform()">
4599 transform2() - L<Imager::Engines/"transform2()">
4601 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
4603 unload_plugin() - L<Imager::Filters/unload_plugin()>
4605 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
4608 write() - L<Imager::Files/write()> - write an image to a file
4610 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
4613 write_types() - L<Imager::Files/read_types()> - list image types Imager
4616 =head1 CONCEPT INDEX
4618 animated GIF - L<Imager::Files/"Writing an animated GIF">
4620 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
4621 L<Imager::ImageTypes/"Common Tags">.
4623 blend - alpha blending one image onto another
4624 L<Imager::Transformations/rubthrough()>
4626 blur - L<Imager::Filters/gaussian>, L<Imager::Filters/conv>
4628 boxes, drawing - L<Imager::Draw/box()>
4630 changes between image - L<Imager::Filters/"Image Difference">
4632 channels, combine into one image - L<Imager::Transformations/combine()>
4634 color - L<Imager::Color>
4636 color names - L<Imager::Color>, L<Imager::Color::Table>
4638 combine modes - L<Imager::Draw/"Combine Types">
4640 compare images - L<Imager::Filters/"Image Difference">
4642 contrast - L<Imager::Filters/contrast>, L<Imager::Filters/autolevels>
4644 convolution - L<Imager::Filters/conv>
4646 cropping - L<Imager::Transformations/crop()>
4648 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4650 C<diff> images - L<Imager::Filters/"Image Difference">
4652 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
4653 L<Imager::Cookbook/"Image spatial resolution">
4655 drawing boxes - L<Imager::Draw/box()>
4657 drawing lines - L<Imager::Draw/line()>
4659 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
4661 error message - L</"ERROR HANDLING">
4663 files, font - L<Imager::Font>
4665 files, image - L<Imager::Files>
4667 filling, types of fill - L<Imager::Fill>
4669 filling, boxes - L<Imager::Draw/box()>
4671 filling, flood fill - L<Imager::Draw/flood_fill()>
4673 flood fill - L<Imager::Draw/flood_fill()>
4675 fonts - L<Imager::Font>
4677 fonts, drawing with - L<Imager::Draw/string()>,
4678 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
4680 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4682 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
4684 fountain fill - L<Imager::Fill/"Fountain fills">,
4685 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4686 L<Imager::Filters/gradgen>
4688 GIF files - L<Imager::Files/"GIF">
4690 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
4692 gradient fill - L<Imager::Fill/"Fountain fills">,
4693 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4694 L<Imager::Filters/gradgen>
4696 gray scale, convert image to - L<Imager::Transformations/convert()>
4698 gaussian blur - L<Imager::Filters/gaussian>
4700 hatch fills - L<Imager::Fill/"Hatched fills">
4702 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4704 invert image - L<Imager::Filters/hardinvert>,
4705 L<Imager::Filters/hardinvertall>
4707 JPEG - L<Imager::Files/"JPEG">
4709 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
4711 lines, drawing - L<Imager::Draw/line()>
4713 matrix - L<Imager::Matrix2d>,
4714 L<Imager::Engines/"Matrix Transformations">,
4715 L<Imager::Font/transform()>
4717 metadata, image - L<Imager::ImageTypes/"Tags">
4719 mosaic - L<Imager::Filters/mosaic>
4721 noise, filter - L<Imager::Filters/noise>
4723 noise, rendered - L<Imager::Filters/turbnoise>,
4724 L<Imager::Filters/radnoise>
4726 paste - L<Imager::Transformations/paste()>,
4727 L<Imager::Transformations/rubthrough()>
4729 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
4730 L<Imager::ImageTypes/new()>
4732 =for stopwords posterize
4734 posterize - L<Imager::Filters/postlevels>
4736 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
4738 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
4740 rectangles, drawing - L<Imager::Draw/box()>
4742 resizing an image - L<Imager::Transformations/scale()>,
4743 L<Imager::Transformations/crop()>
4745 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
4747 saving an image - L<Imager::Files>
4749 scaling - L<Imager::Transformations/scale()>
4751 SGI files - L<Imager::Files/"SGI (RGB, BW)">
4753 sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
4755 size, image - L<Imager::ImageTypes/getwidth()>,
4756 L<Imager::ImageTypes/getheight()>
4758 size, text - L<Imager::Font/bounding_box()>
4760 tags, image metadata - L<Imager::ImageTypes/"Tags">
4762 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
4763 L<Imager::Font::Wrap>
4765 text, wrapping text in an area - L<Imager::Font::Wrap>
4767 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4769 tiles, color - L<Imager::Filters/mosaic>
4771 transparent images - L<Imager::ImageTypes>,
4772 L<Imager::Cookbook/"Transparent PNG">
4774 =for stopwords unsharp
4776 unsharp mask - L<Imager::Filters/unsharpmask>
4778 watermark - L<Imager::Filters/watermark>
4780 writing an image to a file - L<Imager::Files>
4784 Imager doesn't support perl threads.
4786 Imager has limited code to prevent double frees if you create images,
4787 colors etc, and then create a thread, but has no code to prevent two
4788 threads entering Imager's error handling code, and none is likely to
4793 The best place to get help with Imager is the mailing list.
4795 To subscribe send a message with C<subscribe> in the body to:
4797 imager-devel+request@molar.is
4803 L<http://www.molar.is/en/lists/imager-devel/>
4807 where you can also find the mailing list archive.
4809 You can report bugs by pointing your browser at:
4813 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
4817 or by sending an email to:
4821 bug-Imager@rt.cpan.org
4825 Please remember to include the versions of Imager, perl, supporting
4826 libraries, and any relevant code. If you have specific images that
4827 cause the problems, please include those too.
4829 If you don't want to publish your email address on a mailing list you
4830 can use CPAN::Forum:
4832 http://www.cpanforum.com/dist/Imager
4834 You will need to register to post.
4836 =head1 CONTRIBUTING TO IMAGER
4842 If you like or dislike Imager, you can add a public review of Imager
4845 http://cpanratings.perl.org/dist/Imager
4847 =for stopwords Bitcard
4849 This requires a Bitcard account (http://www.bitcard.org).
4851 You can also send email to the maintainer below.
4853 If you send me a bug report via email, it will be copied to Request
4858 I accept patches, preferably against the master branch in git. Please
4859 include an explanation of the reason for why the patch is needed or
4862 Your patch should include regression tests where possible, otherwise
4863 it will be delayed until I get a chance to write them.
4865 To browse Imager's git repository:
4867 http://git.imager.perl.org/imager.git
4871 https://github.com/tonycoz/imager
4875 git clone git://git.imager.perl.org/imager.git
4879 git clone git://github.com/tonycoz/imager.git
4883 Tony Cook <tonyc@cpan.org> is the current maintainer for Imager.
4885 Arnar M. Hrafnkelsson is the original author of Imager.
4887 Many others have contributed to Imager, please see the C<README> for a
4892 Imager is licensed under the same terms as perl itself.
4895 makeblendedfont Fontforge
4897 A test font, generated by the Debian packaged Fontforge,
4898 F<FT2/fontfiles/MMOne.pfb>, contains a Postscript operator definition
4899 copyrighted by Adobe. See F<adobe.txt> in the source for license
4904 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
4905 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
4906 L<Imager::Font>(3), L<Imager::Transformations>(3),
4907 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
4908 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
4910 L<http://imager.perl.org/>
4912 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
4914 Other perl imaging modules include:
4916 L<GD>(3), L<Image::Magick>(3), L<Graphics::Magick>(3),
4917 L<Prima::Image>, L<IPA>.
4919 If you're trying to use Imager for array processing, you should
4920 probably using L<PDL>.