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}=Imager::ImgRaw::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 loading $file";
1610 $work =~ s/\n?Compilation failed in require at .*Imager\.pm line .*\z//m;
1611 $work =~ s/\n/\\n/g;
1612 $file_load_errors{$file} = $work;
1619 # probes for an Imager::File::whatever module
1620 sub _reader_autoload {
1623 return if $formats_low{$type} || $readers{$type};
1625 return unless $type =~ /^\w+$/;
1627 my $file = "Imager/File/\U$type\E.pm";
1630 my $loaded = _load_file($file, \$error);
1631 if (!$loaded && $error =~ /^Can't locate /) {
1632 my $filer = "Imager/File/\U$type\EReader.pm";
1633 $loaded = _load_file($filer, \$error);
1634 if ($error =~ /^Can't locate /) {
1635 $error = "Can't locate $file or $filer";
1639 $reader_load_errors{$type} = $error;
1643 # probes for an Imager::File::whatever module
1644 sub _writer_autoload {
1647 return if $formats_low{$type} || $writers{$type};
1649 return unless $type =~ /^\w+$/;
1651 my $file = "Imager/File/\U$type\E.pm";
1654 my $loaded = _load_file($file, \$error);
1655 if (!$loaded && $error =~ /^Can't locate /) {
1656 my $filew = "Imager/File/\U$type\EWriter.pm";
1657 $loaded = _load_file($filew, \$error);
1658 if ($error =~ /^Can't locate /) {
1659 $error = "Can't locate $file or $filew";
1663 $writer_load_errors{$type} = $error;
1667 sub _fix_gif_positions {
1668 my ($opts, $opt, $msg, @imgs) = @_;
1670 my $positions = $opts->{'gif_positions'};
1672 for my $pos (@$positions) {
1673 my ($x, $y) = @$pos;
1674 my $img = $imgs[$index++];
1675 $img->settag(name=>'gif_left', value=>$x);
1676 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1678 $$msg .= "replaced with the gif_left and gif_top tags";
1683 gif_each_palette=>'gif_local_map',
1684 interlace => 'gif_interlace',
1685 gif_delays => 'gif_delay',
1686 gif_positions => \&_fix_gif_positions,
1687 gif_loop_count => 'gif_loop',
1690 # options that should be converted to colors
1691 my %color_opts = map { $_ => 1 } qw/i_background/;
1694 my ($self, $opts, $prefix, @imgs) = @_;
1696 for my $opt (keys %$opts) {
1698 if ($obsolete_opts{$opt}) {
1699 my $new = $obsolete_opts{$opt};
1700 my $msg = "Obsolete option $opt ";
1702 $new->($opts, $opt, \$msg, @imgs);
1705 $msg .= "replaced with the $new tag ";
1708 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1709 warn $msg if $warn_obsolete && $^W;
1711 next unless $tagname =~ /^\Q$prefix/;
1712 my $value = $opts->{$opt};
1713 if ($color_opts{$opt}) {
1714 $value = _color($value);
1716 $self->_set_error($Imager::ERRSTR);
1721 if (UNIVERSAL::isa($value, "Imager::Color")) {
1722 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1723 for my $img (@imgs) {
1724 $img->settag(name=>$tagname, value=>$tag);
1727 elsif (ref($value) eq 'ARRAY') {
1728 for my $i (0..$#$value) {
1729 my $val = $value->[$i];
1731 if (UNIVERSAL::isa($val, "Imager::Color")) {
1732 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1734 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1737 $self->_set_error("Unknown reference type " . ref($value) .
1738 " supplied in array for $opt");
1744 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1749 $self->_set_error("Unknown reference type " . ref($value) .
1750 " supplied for $opt");
1755 # set it as a tag for every image
1756 for my $img (@imgs) {
1757 $img->settag(name=>$tagname, value=>$value);
1765 # Write an image to file
1768 my %input=(jpegquality=>75,
1778 $self->_set_opts(\%input, "i_", $self)
1781 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1783 my $type = $input{'type'};
1784 if (!$type and $input{file}) {
1785 $type = $FORMATGUESS->($input{file});
1788 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1792 _writer_autoload($type);
1795 if ($writers{$type} && $writers{$type}{single}) {
1796 ($IO, $fh) = $self->_get_writer_io(\%input)
1799 $writers{$type}{single}->($self, $IO, %input, type => $type)
1803 if (!$formats_low{$type}) {
1804 my $write_types = join ', ', sort Imager->write_types();
1805 $self->_set_error("format '$type' not supported - formats $write_types available for writing - $writer_load_errors{$type}");
1809 ($IO, $fh) = $self->_get_writer_io(\%input, $type)
1812 if ( $type eq 'pnm' ) {
1813 $self->_set_opts(\%input, "pnm_", $self)
1815 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1816 $self->{ERRSTR} = $self->_error_as_msg();
1819 $self->{DEBUG} && print "writing a pnm file\n";
1821 elsif ( $type eq 'raw' ) {
1822 $self->_set_opts(\%input, "raw_", $self)
1824 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1825 $self->{ERRSTR} = $self->_error_as_msg();
1828 $self->{DEBUG} && print "writing a raw file\n";
1830 elsif ( $type eq 'bmp' ) {
1831 $self->_set_opts(\%input, "bmp_", $self)
1833 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1834 $self->{ERRSTR} = $self->_error_as_msg;
1837 $self->{DEBUG} && print "writing a bmp file\n";
1839 elsif ( $type eq 'tga' ) {
1840 $self->_set_opts(\%input, "tga_", $self)
1843 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1844 $self->{ERRSTR}=$self->_error_as_msg();
1847 $self->{DEBUG} && print "writing a tga file\n";
1851 if (exists $input{'data'}) {
1852 my $data = io_slurp($IO);
1854 $self->{ERRSTR}='Could not slurp from buffer';
1857 ${$input{data}} = $data;
1863 my ($class, $opts, @images) = @_;
1865 my $type = $opts->{type};
1867 if (!$type && $opts->{'file'}) {
1868 $type = $FORMATGUESS->($opts->{'file'});
1871 $class->_set_error('type parameter missing and not possible to guess from extension');
1874 # translate to ImgRaw
1875 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1876 $class->_set_error('Usage: Imager->write_multi({ options }, @images)');
1879 $class->_set_opts($opts, "i_", @images)
1881 my @work = map $_->{IMG}, @images;
1883 _writer_autoload($type);
1886 if ($writers{$type} && $writers{$type}{multiple}) {
1887 ($IO, $file) = $class->_get_writer_io($opts, $type)
1890 $writers{$type}{multiple}->($class, $IO, $opts, @images)
1894 if (!$formats{$type}) {
1895 my $write_types = join ', ', sort Imager->write_types();
1896 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
1900 ($IO, $file) = $class->_get_writer_io($opts, $type)
1903 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
1907 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
1912 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
1918 if (exists $opts->{'data'}) {
1919 my $data = io_slurp($IO);
1921 Imager->_set_error('Could not slurp from buffer');
1924 ${$opts->{data}} = $data;
1929 # read multiple images from a file
1931 my ($class, %opts) = @_;
1933 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
1936 my $type = $opts{'type'};
1938 $type = i_test_format_probe($IO, -1);
1941 if ($opts{file} && !$type) {
1943 $type = $FORMATGUESS->($opts{file});
1947 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1948 $opts{file} and $msg .= " or file name";
1949 Imager->_set_error($msg);
1953 _reader_autoload($type);
1955 if ($readers{$type} && $readers{$type}{multiple}) {
1956 return $readers{$type}{multiple}->($IO, %opts);
1959 unless ($formats{$type}) {
1960 my $read_types = join ', ', sort Imager->read_types();
1961 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
1966 if ($type eq 'pnm') {
1967 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
1970 my $img = Imager->new;
1971 if ($img->read(%opts, io => $IO, type => $type)) {
1974 Imager->_set_error($img->errstr);
1979 $ERRSTR = _error_as_msg();
1983 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1987 # Destroy an Imager object
1991 # delete $instances{$self};
1992 if (defined($self->{IMG})) {
1993 # the following is now handled by the XS DESTROY method for
1994 # Imager::ImgRaw object
1995 # Re-enabling this will break virtual images
1996 # tested for in t/t020masked.t
1997 # i_img_destroy($self->{IMG});
1998 undef($self->{IMG});
2000 # print "Destroy Called on an empty image!\n"; # why did I put this here??
2004 # Perform an inplace filter of an image
2005 # that is the image will be overwritten with the data
2011 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2013 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
2015 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
2016 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
2019 if ($filters{$input{'type'}}{names}) {
2020 my $names = $filters{$input{'type'}}{names};
2021 for my $name (keys %$names) {
2022 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
2023 $input{$name} = $names->{$name}{$input{$name}};
2027 if (defined($filters{$input{'type'}}{defaults})) {
2028 %hsh=( image => $self->{IMG},
2030 %{$filters{$input{'type'}}{defaults}},
2033 %hsh=( image => $self->{IMG},
2038 my @cs=@{$filters{$input{'type'}}{callseq}};
2041 if (!defined($hsh{$_})) {
2042 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
2047 local $SIG{__DIE__}; # we don't want this processed by confess, etc
2048 &{$filters{$input{'type'}}{callsub}}(%hsh);
2051 chomp($self->{ERRSTR} = $@);
2057 $self->{DEBUG} && print "callseq is: @cs\n";
2058 $self->{DEBUG} && print "matching callseq is: @b\n";
2063 sub register_filter {
2065 my %hsh = ( defaults => {}, @_ );
2068 or die "register_filter() with no type\n";
2069 defined $hsh{callsub}
2070 or die "register_filter() with no callsub\n";
2071 defined $hsh{callseq}
2072 or die "register_filter() with no callseq\n";
2074 exists $filters{$hsh{type}}
2077 $filters{$hsh{type}} = \%hsh;
2082 sub scale_calculate {
2085 my %opts = ('type'=>'max', @_);
2087 # none of these should be references
2088 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2089 if (defined $opts{$name} && ref $opts{$name}) {
2090 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2095 my ($x_scale, $y_scale);
2096 my $width = $opts{width};
2097 my $height = $opts{height};
2099 defined $width or $width = $self->getwidth;
2100 defined $height or $height = $self->getheight;
2103 unless (defined $width && defined $height) {
2104 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2109 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2110 $x_scale = $opts{'xscalefactor'};
2111 $y_scale = $opts{'yscalefactor'};
2113 elsif ($opts{'xscalefactor'}) {
2114 $x_scale = $opts{'xscalefactor'};
2115 $y_scale = $opts{'scalefactor'} || $x_scale;
2117 elsif ($opts{'yscalefactor'}) {
2118 $y_scale = $opts{'yscalefactor'};
2119 $x_scale = $opts{'scalefactor'} || $y_scale;
2122 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2125 # work out the scaling
2126 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2127 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2128 $opts{ypixels} / $height );
2129 if ($opts{'type'} eq 'min') {
2130 $x_scale = $y_scale = _min($xpix,$ypix);
2132 elsif ($opts{'type'} eq 'max') {
2133 $x_scale = $y_scale = _max($xpix,$ypix);
2135 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2140 $self->_set_error('invalid value for type parameter');
2143 } elsif ($opts{xpixels}) {
2144 $x_scale = $y_scale = $opts{xpixels} / $width;
2146 elsif ($opts{ypixels}) {
2147 $x_scale = $y_scale = $opts{ypixels}/$height;
2149 elsif ($opts{constrain} && ref $opts{constrain}
2150 && $opts{constrain}->can('constrain')) {
2151 # we've been passed an Image::Math::Constrain object or something
2152 # that looks like one
2154 (undef, undef, $scalefactor)
2155 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2156 unless ($scalefactor) {
2157 $self->_set_error('constrain method failed on constrain parameter');
2160 $x_scale = $y_scale = $scalefactor;
2163 my $new_width = int($x_scale * $width + 0.5);
2164 $new_width > 0 or $new_width = 1;
2165 my $new_height = int($y_scale * $height + 0.5);
2166 $new_height > 0 or $new_height = 1;
2168 return ($x_scale, $y_scale, $new_width, $new_height);
2172 # Scale an image to requested size and return the scaled version
2176 my %opts = (qtype=>'normal' ,@_);
2177 my $img = Imager->new();
2178 my $tmp = Imager->new();
2180 unless (defined wantarray) {
2181 my @caller = caller;
2182 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2186 unless ($self->{IMG}) {
2187 $self->_set_error('empty input image');
2191 my ($x_scale, $y_scale, $new_width, $new_height) =
2192 $self->scale_calculate(%opts)
2195 if ($opts{qtype} eq 'normal') {
2196 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2197 if ( !defined($tmp->{IMG}) ) {
2198 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2201 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2202 if ( !defined($img->{IMG}) ) {
2203 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2209 elsif ($opts{'qtype'} eq 'preview') {
2210 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2211 if ( !defined($img->{IMG}) ) {
2212 $self->{ERRSTR}='unable to scale image';
2217 elsif ($opts{'qtype'} eq 'mixing') {
2218 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2219 unless ($img->{IMG}) {
2220 $self->_set_error(Imager->_error_as_msg);
2226 $self->_set_error('invalid value for qtype parameter');
2231 # Scales only along the X axis
2235 my %opts = ( scalefactor=>0.5, @_ );
2237 unless (defined wantarray) {
2238 my @caller = caller;
2239 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2243 unless ($self->{IMG}) {
2244 $self->{ERRSTR} = 'empty input image';
2248 my $img = Imager->new();
2250 my $scalefactor = $opts{scalefactor};
2252 if ($opts{pixels}) {
2253 $scalefactor = $opts{pixels} / $self->getwidth();
2256 unless ($self->{IMG}) {
2257 $self->{ERRSTR}='empty input image';
2261 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2263 if ( !defined($img->{IMG}) ) {
2264 $self->{ERRSTR} = 'unable to scale image';
2271 # Scales only along the Y axis
2275 my %opts = ( scalefactor => 0.5, @_ );
2277 unless (defined wantarray) {
2278 my @caller = caller;
2279 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2283 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2285 my $img = Imager->new();
2287 my $scalefactor = $opts{scalefactor};
2289 if ($opts{pixels}) {
2290 $scalefactor = $opts{pixels} / $self->getheight();
2293 unless ($self->{IMG}) {
2294 $self->{ERRSTR} = 'empty input image';
2297 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2299 if ( !defined($img->{IMG}) ) {
2300 $self->{ERRSTR} = 'unable to scale image';
2307 # Transform returns a spatial transformation of the input image
2308 # this moves pixels to a new location in the returned image.
2309 # NOTE - should make a utility function to check transforms for
2314 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2316 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2318 # print Dumper(\%opts);
2321 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2323 eval ("use Affix::Infix2Postfix;");
2326 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2329 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2330 {op=>'-',trans=>'Sub'},
2331 {op=>'*',trans=>'Mult'},
2332 {op=>'/',trans=>'Div'},
2333 {op=>'-','type'=>'unary',trans=>'u-'},
2335 {op=>'func','type'=>'unary'}],
2336 'grouping'=>[qw( \( \) )],
2337 'func'=>[qw( sin cos )],
2342 @xt=$I2P->translate($opts{'xexpr'});
2343 @yt=$I2P->translate($opts{'yexpr'});
2345 $numre=$I2P->{'numre'};
2348 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2349 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2350 @{$opts{'parm'}}=@pt;
2353 # print Dumper(\%opts);
2355 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2356 $self->{ERRSTR}='transform: no xopcodes given.';
2360 @op=@{$opts{'xopcodes'}};
2362 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2363 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2366 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2372 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2373 $self->{ERRSTR}='transform: no yopcodes given.';
2377 @op=@{$opts{'yopcodes'}};
2379 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2380 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2383 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2388 if ( !exists $opts{'parm'}) {
2389 $self->{ERRSTR}='transform: no parameter arg given.';
2393 # print Dumper(\@ropx);
2394 # print Dumper(\@ropy);
2395 # print Dumper(\@ropy);
2397 my $img = Imager->new();
2398 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2399 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2405 my ($opts, @imgs) = @_;
2407 require "Imager/Expr.pm";
2409 $opts->{variables} = [ qw(x y) ];
2410 my ($width, $height) = @{$opts}{qw(width height)};
2412 $width ||= $imgs[0]->getwidth();
2413 $height ||= $imgs[0]->getheight();
2415 for my $img (@imgs) {
2416 $opts->{constants}{"w$img_num"} = $img->getwidth();
2417 $opts->{constants}{"h$img_num"} = $img->getheight();
2418 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2419 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2424 $opts->{constants}{w} = $width;
2425 $opts->{constants}{cx} = $width/2;
2428 $Imager::ERRSTR = "No width supplied";
2432 $opts->{constants}{h} = $height;
2433 $opts->{constants}{cy} = $height/2;
2436 $Imager::ERRSTR = "No height supplied";
2439 my $code = Imager::Expr->new($opts);
2441 $Imager::ERRSTR = Imager::Expr::error();
2444 my $channels = $opts->{channels} || 3;
2445 unless ($channels >= 1 && $channels <= 4) {
2446 return Imager->_set_error("channels must be an integer between 1 and 4");
2449 my $img = Imager->new();
2450 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2451 $channels, $code->code(),
2452 $code->nregs(), $code->cregs(),
2453 [ map { $_->{IMG} } @imgs ]);
2454 if (!defined $img->{IMG}) {
2455 $Imager::ERRSTR = Imager->_error_as_msg();
2466 unless ($self->{IMG}) {
2467 $self->{ERRSTR}='empty input image';
2470 unless ($opts{src} && $opts{src}->{IMG}) {
2471 $self->{ERRSTR}='empty input image for src';
2475 %opts = (src_minx => 0,
2477 src_maxx => $opts{src}->getwidth(),
2478 src_maxy => $opts{src}->getheight(),
2482 defined $tx or $tx = $opts{left};
2483 defined $tx or $tx = 0;
2486 defined $ty or $ty = $opts{top};
2487 defined $ty or $ty = 0;
2489 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2490 $opts{src_minx}, $opts{src_miny},
2491 $opts{src_maxx}, $opts{src_maxy})) {
2492 $self->_set_error($self->_error_as_msg());
2509 unless ($self->{IMG}) {
2510 $self->_set_error("compose: empty input image");
2514 unless ($opts{src}) {
2515 $self->_set_error("compose: src parameter missing");
2519 unless ($opts{src}{IMG}) {
2520 $self->_set_error("compose: src parameter empty image");
2523 my $src = $opts{src};
2525 my $left = $opts{left};
2526 defined $left or $left = $opts{tx};
2527 defined $left or $left = 0;
2529 my $top = $opts{top};
2530 defined $top or $top = $opts{ty};
2531 defined $top or $top = 0;
2533 my $src_left = $opts{src_left};
2534 defined $src_left or $src_left = $opts{src_minx};
2535 defined $src_left or $src_left = 0;
2537 my $src_top = $opts{src_top};
2538 defined $src_top or $src_top = $opts{src_miny};
2539 defined $src_top or $src_top = 0;
2541 my $width = $opts{width};
2542 if (!defined $width && defined $opts{src_maxx}) {
2543 $width = $opts{src_maxx} - $src_left;
2545 defined $width or $width = $src->getwidth() - $src_left;
2547 my $height = $opts{height};
2548 if (!defined $height && defined $opts{src_maxy}) {
2549 $height = $opts{src_maxy} - $src_top;
2551 defined $height or $height = $src->getheight() - $src_top;
2553 my $combine = $self->_combine($opts{combine}, 'normal');
2556 unless ($opts{mask}{IMG}) {
2557 $self->_set_error("compose: mask parameter empty image");
2561 my $mask_left = $opts{mask_left};
2562 defined $mask_left or $mask_left = $opts{mask_minx};
2563 defined $mask_left or $mask_left = 0;
2565 my $mask_top = $opts{mask_top};
2566 defined $mask_top or $mask_top = $opts{mask_miny};
2567 defined $mask_top or $mask_top = 0;
2569 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2570 $left, $top, $src_left, $src_top,
2571 $mask_left, $mask_top, $width, $height,
2572 $combine, $opts{opacity})) {
2573 $self->_set_error(Imager->_error_as_msg);
2578 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2579 $width, $height, $combine, $opts{opacity})) {
2580 $self->_set_error(Imager->_error_as_msg);
2591 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2593 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2594 $dir = $xlate{$opts{'dir'}};
2595 return $self if i_flipxy($self->{IMG}, $dir);
2603 unless (defined wantarray) {
2604 my @caller = caller;
2605 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2609 if (defined $opts{right}) {
2610 my $degrees = $opts{right};
2612 $degrees += 360 * int(((-$degrees)+360)/360);
2614 $degrees = $degrees % 360;
2615 if ($degrees == 0) {
2616 return $self->copy();
2618 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2619 my $result = Imager->new();
2620 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2624 $self->{ERRSTR} = $self->_error_as_msg();
2629 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2633 elsif (defined $opts{radians} || defined $opts{degrees}) {
2634 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
2636 my $back = $opts{back};
2637 my $result = Imager->new;
2639 $back = _color($back);
2641 $self->_set_error(Imager->errstr);
2645 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2648 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2650 if ($result->{IMG}) {
2654 $self->{ERRSTR} = $self->_error_as_msg();
2659 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2664 sub matrix_transform {
2668 unless (defined wantarray) {
2669 my @caller = caller;
2670 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2674 if ($opts{matrix}) {
2675 my $xsize = $opts{xsize} || $self->getwidth;
2676 my $ysize = $opts{ysize} || $self->getheight;
2678 my $result = Imager->new;
2680 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2681 $opts{matrix}, $opts{back})
2685 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2693 $self->{ERRSTR} = "matrix parameter required";
2699 *yatf = \&matrix_transform;
2701 # These two are supported for legacy code only
2704 return Imager::Color->new(@_);
2708 return Imager::Color::set(@_);
2711 # Draws a box between the specified corner points.
2714 my $raw = $self->{IMG};
2717 $self->{ERRSTR}='empty input image';
2723 my ($xmin, $ymin, $xmax, $ymax);
2724 if (exists $opts{'box'}) {
2725 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2726 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2727 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2728 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2731 defined($xmin = $opts{xmin}) or $xmin = 0;
2732 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2733 defined($ymin = $opts{ymin}) or $ymin = 0;
2734 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2737 if ($opts{filled}) {
2738 my $color = $opts{'color'};
2740 if (defined $color) {
2741 unless (_is_color_object($color)) {
2742 $color = _color($color);
2744 $self->{ERRSTR} = $Imager::ERRSTR;
2750 $color = i_color_new(255,255,255,255);
2753 if ($color->isa("Imager::Color")) {
2754 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2757 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2760 elsif ($opts{fill}) {
2761 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2762 # assume it's a hash ref
2763 require 'Imager/Fill.pm';
2764 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2765 $self->{ERRSTR} = $Imager::ERRSTR;
2769 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2772 my $color = $opts{'color'};
2773 if (defined $color) {
2774 unless (_is_color_object($color)) {
2775 $color = _color($color);
2777 $self->{ERRSTR} = $Imager::ERRSTR;
2783 $color = i_color_new(255, 255, 255, 255);
2786 $self->{ERRSTR} = $Imager::ERRSTR;
2789 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2797 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2798 my $dflcl= [ 255, 255, 255, 255];
2803 'r'=>_min($self->getwidth(),$self->getheight())/3,
2804 'x'=>$self->getwidth()/2,
2805 'y'=>$self->getheight()/2,
2812 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2813 # assume it's a hash ref
2814 require 'Imager/Fill.pm';
2815 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2816 $self->{ERRSTR} = $Imager::ERRSTR;
2820 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2821 $opts{'d2'}, $opts{fill}{fill});
2823 elsif ($opts{filled}) {
2824 my $color = _color($opts{'color'});
2826 $self->{ERRSTR} = $Imager::ERRSTR;
2829 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2830 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2834 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2835 $opts{'d1'}, $opts{'d2'}, $color);
2839 my $color = _color($opts{'color'});
2840 if ($opts{d2} - $opts{d1} >= 360) {
2841 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
2844 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
2850 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2851 # assume it's a hash ref
2852 require 'Imager/Fill.pm';
2853 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2854 $self->{ERRSTR} = $Imager::ERRSTR;
2858 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2859 $opts{'d2'}, $opts{fill}{fill});
2862 my $color = _color($opts{'color'});
2864 $self->{ERRSTR} = $Imager::ERRSTR;
2867 if ($opts{filled}) {
2868 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2869 $opts{'d1'}, $opts{'d2'}, $color);
2872 if ($opts{d1} == 0 && $opts{d2} == 361) {
2873 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
2876 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
2882 $self->_set_error($self->_error_as_msg);
2889 # Draws a line from one point to the other
2890 # the endpoint is set if the endp parameter is set which it is by default.
2891 # to turn of the endpoint being set use endp=>0 when calling line.
2895 my $dflcl=i_color_new(0,0,0,0);
2896 my %opts=(color=>$dflcl,
2899 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2901 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
2902 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
2904 my $color = _color($opts{'color'});
2906 $self->{ERRSTR} = $Imager::ERRSTR;
2910 $opts{antialias} = $opts{aa} if defined $opts{aa};
2911 if ($opts{antialias}) {
2912 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2913 $color, $opts{endp});
2915 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
2916 $color, $opts{endp});
2921 # Draws a line between an ordered set of points - It more or less just transforms this
2922 # into a list of lines.
2926 my ($pt,$ls,@points);
2927 my $dflcl=i_color_new(0,0,0,0);
2928 my %opts=(color=>$dflcl,@_);
2930 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2932 if (exists($opts{points})) { @points=@{$opts{points}}; }
2933 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
2934 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
2937 # print Dumper(\@points);
2939 my $color = _color($opts{'color'});
2941 $self->{ERRSTR} = $Imager::ERRSTR;
2944 $opts{antialias} = $opts{aa} if defined $opts{aa};
2945 if ($opts{antialias}) {
2948 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
2955 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
2965 my ($pt,$ls,@points);
2966 my $dflcl = i_color_new(0,0,0,0);
2967 my %opts = (color=>$dflcl, @_);
2969 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2971 if (exists($opts{points})) {
2972 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
2973 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
2976 if (!exists $opts{'x'} or !exists $opts{'y'}) {
2977 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
2980 if ($opts{'fill'}) {
2981 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
2982 # assume it's a hash ref
2983 require 'Imager/Fill.pm';
2984 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
2985 $self->{ERRSTR} = $Imager::ERRSTR;
2989 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
2990 $opts{'fill'}{'fill'});
2993 my $color = _color($opts{'color'});
2995 $self->{ERRSTR} = $Imager::ERRSTR;
2998 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3005 # this the multipoint bezier curve
3006 # this is here more for testing that actual usage since
3007 # this is not a good algorithm. Usually the curve would be
3008 # broken into smaller segments and each done individually.
3012 my ($pt,$ls,@points);
3013 my $dflcl=i_color_new(0,0,0,0);
3014 my %opts=(color=>$dflcl,@_);
3016 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3018 if (exists $opts{points}) {
3019 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
3020 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
3023 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
3024 $self->{ERRSTR}='Missing or invalid points.';
3028 my $color = _color($opts{'color'});
3030 $self->{ERRSTR} = $Imager::ERRSTR;
3033 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
3039 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
3042 unless (exists $opts{'x'} && exists $opts{'y'}) {
3043 $self->{ERRSTR} = "missing seed x and y parameters";
3047 if ($opts{border}) {
3048 my $border = _color($opts{border});
3050 $self->_set_error($Imager::ERRSTR);
3054 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3055 # assume it's a hash ref
3056 require Imager::Fill;
3057 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3058 $self->{ERRSTR} = $Imager::ERRSTR;
3062 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3063 $opts{fill}{fill}, $border);
3066 my $color = _color($opts{'color'});
3068 $self->{ERRSTR} = $Imager::ERRSTR;
3071 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3078 $self->{ERRSTR} = $self->_error_as_msg();
3084 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3085 # assume it's a hash ref
3086 require 'Imager/Fill.pm';
3087 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3088 $self->{ERRSTR} = $Imager::ERRSTR;
3092 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3095 my $color = _color($opts{'color'});
3097 $self->{ERRSTR} = $Imager::ERRSTR;
3100 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3106 $self->{ERRSTR} = $self->_error_as_msg();
3113 my ($self, %opts) = @_;
3115 $self->_valid_image("setpixel")
3118 my $color = $opts{color};
3119 unless (defined $color) {
3120 $color = $self->{fg};
3121 defined $color or $color = NC(255, 255, 255);
3124 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3125 unless ($color = _color($color, 'setpixel')) {
3126 $self->_set_error("setpixel: " . Imager->errstr);
3131 unless (exists $opts{'x'} && exists $opts{'y'}) {
3132 $self->_set_error('setpixel: missing x or y parameter');
3138 if (ref $x || ref $y) {
3139 $x = ref $x ? $x : [ $x ];
3140 $y = ref $y ? $y : [ $y ];
3142 $self->_set_error("setpixel: x is a reference to an empty array");
3146 $self->_set_error("setpixel: y is a reference to an empty array");
3150 # make both the same length, replicating the last element
3152 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3155 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3159 if ($color->isa('Imager::Color')) {
3160 for my $i (0..$#$x) {
3161 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3166 for my $i (0..$#$x) {
3167 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3175 if ($color->isa('Imager::Color')) {
3176 i_ppix($self->{IMG}, $x, $y, $color)
3180 i_ppixf($self->{IMG}, $x, $y, $color)
3191 my %opts = ( "type"=>'8bit', @_);
3193 $self->_valid_image("getpixel")
3196 unless (exists $opts{'x'} && exists $opts{'y'}) {
3197 $self->_set_error('getpixel: missing x or y parameter');
3203 my $type = $opts{'type'};
3204 if (ref $x || ref $y) {
3205 $x = ref $x ? $x : [ $x ];
3206 $y = ref $y ? $y : [ $y ];
3208 $self->_set_error("getpixel: x is a reference to an empty array");
3212 $self->_set_error("getpixel: y is a reference to an empty array");
3216 # make both the same length, replicating the last element
3218 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3221 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3225 if ($type eq '8bit') {
3226 for my $i (0..$#$x) {
3227 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3230 elsif ($type eq 'float' || $type eq 'double') {
3231 for my $i (0..$#$x) {
3232 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3236 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3239 return wantarray ? @result : \@result;
3242 if ($type eq '8bit') {
3243 return i_get_pixel($self->{IMG}, $x, $y);
3245 elsif ($type eq 'float' || $type eq 'double') {
3246 return i_gpixf($self->{IMG}, $x, $y);
3249 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3257 my %opts = ( type => '8bit', x=>0, @_);
3259 $self->_valid_image or return;
3261 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3263 unless (defined $opts{'y'}) {
3264 $self->_set_error("missing y parameter");
3268 if ($opts{type} eq '8bit') {
3269 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3272 elsif ($opts{type} eq 'float') {
3273 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3276 elsif ($opts{type} eq 'index') {
3277 unless (i_img_type($self->{IMG})) {
3278 $self->_set_error("type => index only valid on paletted images");
3281 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3285 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3292 my %opts = ( x=>0, @_);
3294 $self->_valid_image or return;
3296 unless (defined $opts{'y'}) {
3297 $self->_set_error("missing y parameter");
3302 if (ref $opts{pixels} && @{$opts{pixels}}) {
3303 # try to guess the type
3304 if ($opts{pixels}[0]->isa('Imager::Color')) {
3305 $opts{type} = '8bit';
3307 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3308 $opts{type} = 'float';
3311 $self->_set_error("missing type parameter and could not guess from pixels");
3317 $opts{type} = '8bit';
3321 if ($opts{type} eq '8bit') {
3322 if (ref $opts{pixels}) {
3323 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3326 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3329 elsif ($opts{type} eq 'float') {
3330 if (ref $opts{pixels}) {
3331 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3334 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3337 elsif ($opts{type} eq 'index') {
3338 if (ref $opts{pixels}) {
3339 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3342 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3346 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3353 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3355 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3357 unless (defined $opts{'y'}) {
3358 $self->_set_error("missing y parameter");
3362 if ($opts{target}) {
3363 my $target = $opts{target};
3364 my $offset = $opts{offset};
3365 if ($opts{type} eq '8bit') {
3366 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3367 $opts{y}, $opts{channels})
3369 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3370 return scalar(@samples);
3372 elsif ($opts{type} eq 'float') {
3373 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3374 $opts{y}, $opts{channels});
3375 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3376 return scalar(@samples);
3378 elsif ($opts{type} =~ /^(\d+)bit$/) {
3382 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3383 $opts{y}, $bits, $target,
3384 $offset, $opts{channels});
3385 unless (defined $count) {
3386 $self->_set_error(Imager->_error_as_msg);
3393 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3398 if ($opts{type} eq '8bit') {
3399 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3400 $opts{y}, $opts{channels});
3402 elsif ($opts{type} eq 'float') {
3403 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3404 $opts{y}, $opts{channels});
3406 elsif ($opts{type} =~ /^(\d+)bit$/) {
3410 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3411 $opts{y}, $bits, \@data, 0, $opts{channels})
3416 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3424 my %opts = ( x => 0, offset => 0, @_ );
3426 unless ($self->{IMG}) {
3427 $self->_set_error('setsamples: empty input image');
3431 my $data = $opts{data};
3432 unless(defined $data) {
3433 $self->_set_error('setsamples: data parameter missing');
3437 my $type = $opts{type};
3438 defined $type or $type = '8bit';
3440 my $width = defined $opts{width} ? $opts{width}
3441 : $self->getwidth() - $opts{x};
3444 if ($type eq '8bit') {
3445 $count = i_psamp($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3446 $data, $opts{offset}, $width);
3448 elsif ($type eq 'float') {
3449 $count = i_psampf($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3450 $data, $opts{offset}, $width);
3452 elsif ($type =~ /^([0-9]+)bit$/) {
3455 unless (ref $data) {
3456 $self->_set_error("setsamples: data must be an array ref for type not 8bit or float");
3460 $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3461 $opts{channels}, $data, $opts{offset},
3465 $self->_set_error('setsamples: type parameter invalid');
3469 unless (defined $count) {
3470 $self->_set_error(Imager->_error_as_msg);
3477 # make an identity matrix of the given size
3481 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3482 for my $c (0 .. ($size-1)) {
3483 $matrix->[$c][$c] = 1;
3488 # general function to convert an image
3490 my ($self, %opts) = @_;
3493 unless (defined wantarray) {
3494 my @caller = caller;
3495 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3499 # the user can either specify a matrix or preset
3500 # the matrix overrides the preset
3501 if (!exists($opts{matrix})) {
3502 unless (exists($opts{preset})) {
3503 $self->{ERRSTR} = "convert() needs a matrix or preset";
3507 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3508 # convert to greyscale, keeping the alpha channel if any
3509 if ($self->getchannels == 3) {
3510 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3512 elsif ($self->getchannels == 4) {
3513 # preserve the alpha channel
3514 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3519 $matrix = _identity($self->getchannels);
3522 elsif ($opts{preset} eq 'noalpha') {
3523 # strip the alpha channel
3524 if ($self->getchannels == 2 or $self->getchannels == 4) {
3525 $matrix = _identity($self->getchannels);
3526 pop(@$matrix); # lose the alpha entry
3529 $matrix = _identity($self->getchannels);
3532 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3534 $matrix = [ [ 1 ] ];
3536 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3537 $matrix = [ [ 0, 1 ] ];
3539 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3540 $matrix = [ [ 0, 0, 1 ] ];
3542 elsif ($opts{preset} eq 'alpha') {
3543 if ($self->getchannels == 2 or $self->getchannels == 4) {
3544 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3547 # the alpha is just 1 <shrug>
3548 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3551 elsif ($opts{preset} eq 'rgb') {
3552 if ($self->getchannels == 1) {
3553 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3555 elsif ($self->getchannels == 2) {
3556 # preserve the alpha channel
3557 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3560 $matrix = _identity($self->getchannels);
3563 elsif ($opts{preset} eq 'addalpha') {
3564 if ($self->getchannels == 1) {
3565 $matrix = _identity(2);
3567 elsif ($self->getchannels == 3) {
3568 $matrix = _identity(4);
3571 $matrix = _identity($self->getchannels);
3575 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3581 $matrix = $opts{matrix};
3584 my $new = Imager->new;
3585 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3586 unless ($new->{IMG}) {
3587 # most likely a bad matrix
3588 $self->{ERRSTR} = _error_as_msg();
3594 # combine channels from multiple input images, a class method
3596 my ($class, %opts) = @_;
3598 my $src = delete $opts{src};
3600 $class->_set_error("src parameter missing");
3605 for my $img (@$src) {
3606 unless (eval { $img->isa("Imager") }) {
3607 $class->_set_error("src must contain image objects");
3610 unless ($img->{IMG}) {
3611 $class->_set_error("empty input image");
3614 push @imgs, $img->{IMG};
3617 if (my $channels = delete $opts{channels}) {
3618 $result = i_combine(\@imgs, $channels);
3621 $result = i_combine(\@imgs);
3624 $class->_set_error($class->_error_as_msg);
3628 my $img = $class->new;
3629 $img->{IMG} = $result;
3635 # general function to map an image through lookup tables
3638 my ($self, %opts) = @_;
3639 my @chlist = qw( red green blue alpha );
3641 if (!exists($opts{'maps'})) {
3642 # make maps from channel maps
3644 for $chnum (0..$#chlist) {
3645 if (exists $opts{$chlist[$chnum]}) {
3646 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3647 } elsif (exists $opts{'all'}) {
3648 $opts{'maps'}[$chnum] = $opts{'all'};
3652 if ($opts{'maps'} and $self->{IMG}) {
3653 i_map($self->{IMG}, $opts{'maps'} );
3659 my ($self, %opts) = @_;
3661 defined $opts{mindist} or $opts{mindist} = 0;
3663 defined $opts{other}
3664 or return $self->_set_error("No 'other' parameter supplied");
3665 defined $opts{other}{IMG}
3666 or return $self->_set_error("No image data in 'other' image");
3669 or return $self->_set_error("No image data");
3671 my $result = Imager->new;
3672 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3674 or return $self->_set_error($self->_error_as_msg());
3679 # destructive border - image is shrunk by one pixel all around
3682 my ($self,%opts)=@_;
3683 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3684 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3688 # Get the width of an image
3693 if (my $raw = $self->{IMG}) {
3694 return i_img_get_width($raw);
3697 $self->{ERRSTR} = 'image is empty'; return undef;
3701 # Get the height of an image
3706 if (my $raw = $self->{IMG}) {
3707 return i_img_get_height($raw);
3710 $self->{ERRSTR} = 'image is empty'; return undef;
3714 # Get number of channels in an image
3718 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3719 return i_img_getchannels($self->{IMG});
3726 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
3727 return i_img_getmask($self->{IMG});
3735 if (!defined($self->{IMG})) {
3736 $self->{ERRSTR} = 'image is empty';
3739 unless (defined $opts{mask}) {
3740 $self->_set_error("mask parameter required");
3743 i_img_setmask( $self->{IMG} , $opts{mask} );
3748 # Get number of colors in an image
3752 my %opts=('maxcolors'=>2**30,@_);
3753 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
3754 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
3755 return ($rc==-1? undef : $rc);
3758 # Returns a reference to a hash. The keys are colour named (packed) and the
3759 # values are the number of pixels in this colour.
3760 sub getcolorusagehash {
3763 my %opts = ( maxcolors => 2**30, @_ );
3764 my $max_colors = $opts{maxcolors};
3765 unless (defined $max_colors && $max_colors > 0) {
3766 $self->_set_error('maxcolors must be a positive integer');
3770 unless (defined $self->{IMG}) {
3771 $self->_set_error('empty input image');
3775 my $channels= $self->getchannels;
3776 # We don't want to look at the alpha channel, because some gifs using it
3777 # doesn't define it for every colour (but only for some)
3778 $channels -= 1 if $channels == 2 or $channels == 4;
3780 my $height = $self->getheight;
3781 for my $y (0 .. $height - 1) {
3782 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
3783 while (length $colors) {
3784 $color_use{ substr($colors, 0, $channels, '') }++;
3786 keys %color_use > $max_colors
3792 # This will return a ordered array of the colour usage. Kind of the sorted
3793 # version of the values of the hash returned by getcolorusagehash.
3794 # You might want to add safety checks and change the names, etc...
3798 my %opts = ( maxcolors => 2**30, @_ );
3799 my $max_colors = $opts{maxcolors};
3800 unless (defined $max_colors && $max_colors > 0) {
3801 $self->_set_error('maxcolors must be a positive integer');
3805 unless (defined $self->{IMG}) {
3806 $self->_set_error('empty input image');
3810 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
3813 # draw string to an image
3817 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
3819 my %input=('x'=>0, 'y'=>0, @_);
3820 defined($input{string}) or $input{string} = $input{text};
3822 unless(defined $input{string}) {
3823 $self->{ERRSTR}="missing required parameter 'string'";
3827 unless($input{font}) {
3828 $self->{ERRSTR}="missing required parameter 'font'";
3832 unless ($input{font}->draw(image=>$self, %input)) {
3844 unless ($self->{IMG}) {
3845 $self->{ERRSTR}='empty input image';
3854 my %input=('x'=>0, 'y'=>0, @_);
3855 defined $input{string}
3856 or $input{string} = $input{text};
3858 unless(exists $input{string}) {
3859 $self->_set_error("missing required parameter 'string'");
3863 unless($input{font}) {
3864 $self->_set_error("missing required parameter 'font'");
3869 unless (@result = $input{font}->align(image=>$img, %input)) {
3873 return wantarray ? @result : $result[0];
3876 my @file_limit_names = qw/width height bytes/;
3878 sub set_file_limits {
3885 @values{@file_limit_names} = (0) x @file_limit_names;
3888 @values{@file_limit_names} = i_get_image_file_limits();
3891 for my $key (keys %values) {
3892 defined $opts{$key} and $values{$key} = $opts{$key};
3895 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
3898 sub get_file_limits {
3899 i_get_image_file_limits();
3902 # Shortcuts that can be exported
3904 sub newcolor { Imager::Color->new(@_); }
3905 sub newfont { Imager::Font->new(@_); }
3907 require Imager::Color::Float;
3908 return Imager::Color::Float->new(@_);
3911 *NC=*newcolour=*newcolor;
3918 #### Utility routines
3921 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
3925 my ($self, $msg) = @_;
3928 $self->{ERRSTR} = $msg;
3936 # Default guess for the type of an image from extension
3938 my @simple_types = qw(png tga gif raw ico cur xpm mng jng ilbm pcx psd eps);
3942 ( map { $_ => $_ } @simple_types ),
3948 pnm => "pnm", # technically wrong, but historically it works in Imager
3961 sub def_guess_type {
3964 my ($ext) = $name =~ /\.([^.]+)$/
3967 my $type = $ext_types{$ext}
3974 return @combine_types;
3977 # get the minimum of a list
3981 for(@_) { if ($_<$mx) { $mx=$_; }}
3985 # get the maximum of a list
3989 for(@_) { if ($_>$mx) { $mx=$_; }}
3993 # string stuff for iptc headers
3997 $str = substr($str,3);
3998 $str =~ s/[\n\r]//g;
4005 # A little hack to parse iptc headers.
4010 my($caption,$photogr,$headln,$credit);
4012 my $str=$self->{IPTCRAW};
4017 @ar=split(/8BIM/,$str);
4022 @sar=split(/\034\002/);
4023 foreach $item (@sar) {
4024 if ($item =~ m/^x/) {
4025 $caption = _clean($item);
4028 if ($item =~ m/^P/) {
4029 $photogr = _clean($item);
4032 if ($item =~ m/^i/) {
4033 $headln = _clean($item);
4036 if ($item =~ m/^n/) {
4037 $credit = _clean($item);
4043 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
4050 or die "Only C language supported";
4052 require Imager::ExtUtils;
4053 return Imager::ExtUtils->inline_config;
4056 # threads shouldn't try to close raw Imager objects
4057 sub Imager::ImgRaw::CLONE_SKIP { 1 }
4060 # this serves two purposes:
4061 # - a class method to load the file support modules included with Imager
4062 # (or were included, once the library dependent modules are split out)
4063 # - something for Module::ScanDeps to analyze
4064 # https://rt.cpan.org/Ticket/Display.html?id=6566
4066 eval { require Imager::File::GIF };
4067 eval { require Imager::File::JPEG };
4068 eval { require Imager::File::PNG };
4069 eval { require Imager::File::SGI };
4070 eval { require Imager::File::TIFF };
4071 eval { require Imager::File::ICO };
4072 eval { require Imager::Font::W32 };
4073 eval { require Imager::Font::FT2 };
4074 eval { require Imager::Font::T1 };
4077 # backward compatibility for %formats
4078 package Imager::FORMATS;
4080 use constant IX_FORMATS => 0;
4081 use constant IX_LIST => 1;
4082 use constant IX_INDEX => 2;
4083 use constant IX_CLASSES => 3;
4086 my ($class, $formats, $classes) = @_;
4088 return bless [ $formats, [ ], 0, $classes ], $class;
4092 my ($self, $key) = @_;
4094 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
4097 my $loaded = Imager::_load_file($file, \$error);
4102 if ($error =~ /^Can't locate /) {
4103 $error = "Can't locate $file";
4105 $reader_load_errors{$key} = $writer_load_errors{$key} = $error;
4108 $self->[IX_FORMATS]{$key} = $value;
4114 my ($self, $key) = @_;
4116 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
4118 $self->[IX_CLASSES]{$key} or return undef;
4120 return $self->_check($key);
4124 die "%Imager::formats is not user monifiable";
4128 die "%Imager::formats is not user monifiable";
4132 die "%Imager::formats is not user monifiable";
4136 my ($self, $key) = @_;
4138 if (exists $self->[IX_FORMATS]{$key}) {
4139 my $value = $self->[IX_FORMATS]{$key}
4144 $self->_check($key) or return 1==0;
4152 unless (@{$self->[IX_LIST]}) {
4154 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4155 keys %{$self->[IX_FORMATS]};
4157 for my $key (keys %{$self->[IX_CLASSES]}) {
4158 $self->[IX_FORMATS]{$key} and next;
4160 and push @{$self->[IX_LIST]}, $key;
4164 @{$self->[IX_LIST]} or return;
4165 $self->[IX_INDEX] = 1;
4166 return $self->[IX_LIST][0];
4172 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4175 return $self->[IX_LIST][$self->[IX_INDEX]++];
4181 return scalar @{$self->[IX_LIST]};
4186 # Below is the stub of documentation for your module. You better edit it!
4190 Imager - Perl extension for Generating 24 bit Images
4200 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4205 # see Imager::Files for information on the read() method
4206 my $img = Imager->new(file=>$file)
4207 or die Imager->errstr();
4209 $file =~ s/\.[^.]*$//;
4211 # Create smaller version
4212 # documented in Imager::Transformations
4213 my $thumb = $img->scale(scalefactor=>.3);
4215 # Autostretch individual channels
4216 $thumb->filter(type=>'autolevels');
4218 # try to save in one of these formats
4221 for $format ( qw( png gif jpeg tiff ppm ) ) {
4222 # Check if given format is supported
4223 if ($Imager::formats{$format}) {
4224 $file.="_low.$format";
4225 print "Storing image as: $file\n";
4226 # documented in Imager::Files
4227 $thumb->write(file=>$file) or
4235 Imager is a module for creating and altering images. It can read and
4236 write various image formats, draw primitive shapes like lines,and
4237 polygons, blend multiple images together in various ways, scale, crop,
4238 render text and more.
4240 =head2 Overview of documentation
4246 Imager - This document - Synopsis, Example, Table of Contents and
4251 L<Imager::Tutorial> - a brief introduction to Imager.
4255 L<Imager::Cookbook> - how to do various things with Imager.
4259 L<Imager::ImageTypes> - Basics of constructing image objects with
4260 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4261 8/16/double bits/channel, color maps, channel masks, image tags, color
4262 quantization. Also discusses basic image information methods.
4266 L<Imager::Files> - IO interaction, reading/writing images, format
4271 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4276 L<Imager::Color> - Color specification.
4280 L<Imager::Fill> - Fill pattern specification.
4284 L<Imager::Font> - General font rendering, bounding boxes and font
4289 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4290 blending, pasting, convert and map.
4294 L<Imager::Engines> - Programmable transformations through
4295 C<transform()>, C<transform2()> and C<matrix_transform()>.
4299 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4304 L<Imager::Expr> - Expressions for evaluation engine used by
4309 L<Imager::Matrix2d> - Helper class for affine transformations.
4313 L<Imager::Fountain> - Helper for making gradient profiles.
4317 L<Imager::API> - using Imager's C API
4321 L<Imager::APIRef> - API function reference
4325 L<Imager::Inline> - using Imager's C API from Inline::C
4329 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4333 =head2 Basic Overview
4335 An Image object is created with C<$img = Imager-E<gt>new()>.
4338 $img=Imager->new(); # create empty image
4339 $img->read(file=>'lena.png',type=>'png') or # read image from file
4340 die $img->errstr(); # give an explanation
4341 # if something failed
4343 or if you want to create an empty image:
4345 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4347 This example creates a completely black image of width 400 and height
4350 =head1 ERROR HANDLING
4352 In general a method will return false when it fails, if it does use
4353 the C<errstr()> method to find out why:
4359 Returns the last error message in that context.
4361 If the last error you received was from calling an object method, such
4362 as read, call errstr() as an object method to find out why:
4364 my $image = Imager->new;
4365 $image->read(file => 'somefile.gif')
4366 or die $image->errstr;
4368 If it was a class method then call errstr() as a class method:
4370 my @imgs = Imager->read_multi(file => 'somefile.gif')
4371 or die Imager->errstr;
4373 Note that in some cases object methods are implemented in terms of
4374 class methods so a failing object method may set both.
4378 The C<Imager-E<gt>new> method is described in detail in
4379 L<Imager::ImageTypes>.
4383 Where to find information on methods for Imager class objects.
4385 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4388 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4390 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4393 arc() - L<Imager::Draw/arc()> - draw a filled arc
4395 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4398 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4400 circle() - L<Imager::Draw/circle()> - draw a filled circle
4402 close_log() - L<Imager::ImageTypes/close_log()> - close the Imager
4405 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4406 colors in an image's palette (paletted images only)
4408 combine() - L<Imager::Transformations/combine()> - combine channels
4409 from one or more images.
4411 combines() - L<Imager::Draw/combines()> - return a list of the
4412 different combine type keywords
4414 compose() - L<Imager::Transformations/compose()> - compose one image
4417 convert() - L<Imager::Transformations/convert()> - transform the color
4420 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4423 crop() - L<Imager::Transformations/crop()> - extract part of an image
4425 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4426 used to guess the output file format based on the output file name
4428 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4430 difference() - L<Imager::Filters/difference()> - produce a difference
4431 images from two input images.
4433 errstr() - L</errstr()> - the error from the last failed operation.
4435 filter() - L<Imager::Filters/filter()> - image filtering
4437 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4438 palette, if it has one
4440 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4443 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4446 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4447 samples per pixel for an image
4449 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4450 different colors used by an image (works for direct color images)
4452 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4453 palette, if it has one
4455 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4457 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4459 get_file_limits() - L<Imager::Files/get_file_limits()>
4461 getheight() - L<Imager::ImageTypes/getheight()> - height of the image in
4464 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4466 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4469 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4470 row or partial row of pixels.
4472 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4473 row or partial row of pixels.
4475 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4478 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4481 init() - L<Imager::ImageTypes/init()>
4483 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4484 image write functions should write the image in their bilevel (blank
4485 and white, no gray levels) format
4487 is_logging() L<Imager::ImageTypes/is_logging()> - test if the debug
4490 line() - L<Imager::Draw/line()> - draw an interval
4492 load_plugin() - L<Imager::Filters/load_plugin()>
4494 log() - L<Imager::ImageTypes/log()> - send a message to the debugging
4497 make_palette() - L<Imager::ImageTypes/make_palette()> - produce a
4498 color palette from one or more input images.
4500 map() - L<Imager::Transformations/map()> - remap color
4503 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4505 matrix_transform() - L<Imager::Engines/matrix_transform()>
4507 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4509 NC() - L<Imager::Handy/NC()>
4511 NCF() - L<Imager::Handy/NCF()>
4513 new() - L<Imager::ImageTypes/new()>
4515 newcolor() - L<Imager::Handy/newcolor()>
4517 newcolour() - L<Imager::Handy/newcolour()>
4519 newfont() - L<Imager::Handy/newfont()>
4521 NF() - L<Imager::Handy/NF()>
4523 open() - L<Imager::Files/read()> - an alias for read()
4525 open_log() - L<Imager::ImageTypes/open_log()> - open the debug log.
4529 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4532 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4535 polygon() - L<Imager::Draw/polygon()>
4537 polyline() - L<Imager::Draw/polyline()>
4539 preload() - L<Imager::Files/preload()>
4541 read() - L<Imager::Files/read()> - read a single image from an image file
4543 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
4546 read_types() - L<Imager::Files/read_types()> - list image types Imager
4549 register_filter() - L<Imager::Filters/register_filter()>
4551 register_reader() - L<Imager::Files/register_reader()>
4553 register_writer() - L<Imager::Files/register_writer()>
4555 rotate() - L<Imager::Transformations/rotate()>
4557 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
4558 onto an image and use the alpha channel
4560 scale() - L<Imager::Transformations/scale()>
4562 scale_calculate() - L<Imager::Transformations/scale_calculate()>
4564 scaleX() - L<Imager::Transformations/scaleX()>
4566 scaleY() - L<Imager::Transformations/scaleY()>
4568 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
4571 set_file_limits() - L<Imager::Files/set_file_limits()>
4573 setmask() - L<Imager::ImageTypes/setmask()>
4575 setpixel() - L<Imager::Draw/setpixel()>
4577 setsamples() - L<Imager::Draw/setsamples()>
4579 setscanline() - L<Imager::Draw/setscanline()>
4581 settag() - L<Imager::ImageTypes/settag()>
4583 string() - L<Imager::Draw/string()> - draw text on an image
4585 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
4587 to_paletted() - L<Imager::ImageTypes/to_paletted()>
4589 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
4591 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
4593 to_rgb_double() - L<Imager::ImageTypes/to_rgb_double()> - convert to
4594 double per sample image.
4596 transform() - L<Imager::Engines/"transform()">
4598 transform2() - L<Imager::Engines/"transform2()">
4600 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
4602 unload_plugin() - L<Imager::Filters/unload_plugin()>
4604 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
4607 write() - L<Imager::Files/write()> - write an image to a file
4609 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
4612 write_types() - L<Imager::Files/read_types()> - list image types Imager
4615 =head1 CONCEPT INDEX
4617 animated GIF - L<Imager::Files/"Writing an animated GIF">
4619 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
4620 L<Imager::ImageTypes/"Common Tags">.
4622 blend - alpha blending one image onto another
4623 L<Imager::Transformations/rubthrough()>
4625 blur - L<Imager::Filters/gaussian>, L<Imager::Filters/conv>
4627 boxes, drawing - L<Imager::Draw/box()>
4629 changes between image - L<Imager::Filters/"Image Difference">
4631 channels, combine into one image - L<Imager::Transformations/combine()>
4633 color - L<Imager::Color>
4635 color names - L<Imager::Color>, L<Imager::Color::Table>
4637 combine modes - L<Imager::Draw/"Combine Types">
4639 compare images - L<Imager::Filters/"Image Difference">
4641 contrast - L<Imager::Filters/contrast>, L<Imager::Filters/autolevels>
4643 convolution - L<Imager::Filters/conv>
4645 cropping - L<Imager::Transformations/crop()>
4647 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4649 C<diff> images - L<Imager::Filters/"Image Difference">
4651 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
4652 L<Imager::Cookbook/"Image spatial resolution">
4654 drawing boxes - L<Imager::Draw/box()>
4656 drawing lines - L<Imager::Draw/line()>
4658 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
4660 error message - L</"ERROR HANDLING">
4662 files, font - L<Imager::Font>
4664 files, image - L<Imager::Files>
4666 filling, types of fill - L<Imager::Fill>
4668 filling, boxes - L<Imager::Draw/box()>
4670 filling, flood fill - L<Imager::Draw/flood_fill()>
4672 flood fill - L<Imager::Draw/flood_fill()>
4674 fonts - L<Imager::Font>
4676 fonts, drawing with - L<Imager::Draw/string()>,
4677 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
4679 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4681 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
4683 fountain fill - L<Imager::Fill/"Fountain fills">,
4684 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4685 L<Imager::Filters/gradgen>
4687 GIF files - L<Imager::Files/"GIF">
4689 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
4691 gradient fill - L<Imager::Fill/"Fountain fills">,
4692 L<Imager::Filters/fountain>, L<Imager::Fountain>,
4693 L<Imager::Filters/gradgen>
4695 gray scale, convert image to - L<Imager::Transformations/convert()>
4697 gaussian blur - L<Imager::Filters/gaussian>
4699 hatch fills - L<Imager::Fill/"Hatched fills">
4701 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
4703 invert image - L<Imager::Filters/hardinvert>,
4704 L<Imager::Filters/hardinvertall>
4706 JPEG - L<Imager::Files/"JPEG">
4708 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
4710 lines, drawing - L<Imager::Draw/line()>
4712 matrix - L<Imager::Matrix2d>,
4713 L<Imager::Engines/"Matrix Transformations">,
4714 L<Imager::Font/transform()>
4716 metadata, image - L<Imager::ImageTypes/"Tags">
4718 mosaic - L<Imager::Filters/mosaic>
4720 noise, filter - L<Imager::Filters/noise>
4722 noise, rendered - L<Imager::Filters/turbnoise>,
4723 L<Imager::Filters/radnoise>
4725 paste - L<Imager::Transformations/paste()>,
4726 L<Imager::Transformations/rubthrough()>
4728 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
4729 L<Imager::ImageTypes/new()>
4731 =for stopwords posterize
4733 posterize - L<Imager::Filters/postlevels>
4735 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
4737 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
4739 rectangles, drawing - L<Imager::Draw/box()>
4741 resizing an image - L<Imager::Transformations/scale()>,
4742 L<Imager::Transformations/crop()>
4744 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
4746 saving an image - L<Imager::Files>
4748 scaling - L<Imager::Transformations/scale()>
4750 SGI files - L<Imager::Files/"SGI (RGB, BW)">
4752 sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
4754 size, image - L<Imager::ImageTypes/getwidth()>,
4755 L<Imager::ImageTypes/getheight()>
4757 size, text - L<Imager::Font/bounding_box()>
4759 tags, image metadata - L<Imager::ImageTypes/"Tags">
4761 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
4762 L<Imager::Font::Wrap>
4764 text, wrapping text in an area - L<Imager::Font::Wrap>
4766 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
4768 tiles, color - L<Imager::Filters/mosaic>
4770 transparent images - L<Imager::ImageTypes>,
4771 L<Imager::Cookbook/"Transparent PNG">
4773 =for stopwords unsharp
4775 unsharp mask - L<Imager::Filters/unsharpmask>
4777 watermark - L<Imager::Filters/watermark>
4779 writing an image to a file - L<Imager::Files>
4783 Imager doesn't support perl threads.
4785 Imager has limited code to prevent double frees if you create images,
4786 colors etc, and then create a thread, but has no code to prevent two
4787 threads entering Imager's error handling code, and none is likely to
4792 The best place to get help with Imager is the mailing list.
4794 To subscribe send a message with C<subscribe> in the body to:
4796 imager-devel+request@molar.is
4802 L<http://www.molar.is/en/lists/imager-devel/>
4806 where you can also find the mailing list archive.
4808 You can report bugs by pointing your browser at:
4812 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
4816 or by sending an email to:
4820 bug-Imager@rt.cpan.org
4824 Please remember to include the versions of Imager, perl, supporting
4825 libraries, and any relevant code. If you have specific images that
4826 cause the problems, please include those too.
4828 If you don't want to publish your email address on a mailing list you
4829 can use CPAN::Forum:
4831 http://www.cpanforum.com/dist/Imager
4833 You will need to register to post.
4835 =head1 CONTRIBUTING TO IMAGER
4841 If you like or dislike Imager, you can add a public review of Imager
4844 http://cpanratings.perl.org/dist/Imager
4846 =for stopwords Bitcard
4848 This requires a Bitcard account (http://www.bitcard.org).
4850 You can also send email to the maintainer below.
4852 If you send me a bug report via email, it will be copied to Request
4857 I accept patches, preferably against the master branch in git. Please
4858 include an explanation of the reason for why the patch is needed or
4861 Your patch should include regression tests where possible, otherwise
4862 it will be delayed until I get a chance to write them.
4864 To browse Imager's git repository:
4866 http://git.imager.perl.org/imager.git
4870 https://github.com/tonycoz/imager
4874 git clone git://git.imager.perl.org/imager.git
4878 git clone git://github.com/tonycoz/imager.git
4882 Tony Cook <tonyc@cpan.org> is the current maintainer for Imager.
4884 Arnar M. Hrafnkelsson is the original author of Imager.
4886 Many others have contributed to Imager, please see the C<README> for a
4891 Imager is licensed under the same terms as perl itself.
4894 makeblendedfont Fontforge
4896 A test font, generated by the Debian packaged Fontforge,
4897 F<FT2/fontfiles/MMOne.pfb>, contains a Postscript operator definition
4898 copyrighted by Adobe. See F<adobe.txt> in the source for license
4903 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
4904 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
4905 L<Imager::Font>(3), L<Imager::Transformations>(3),
4906 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
4907 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
4909 L<http://imager.perl.org/>
4911 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
4913 Other perl imaging modules include:
4915 L<GD>(3), L<Image::Magick>(3), L<Graphics::Magick>(3),
4916 L<Prima::Image>, L<IPA>.
4918 If you're trying to use Imager for array processing, you should
4919 probably using L<PDL>.