111 # registered file readers
114 # registered file writers
117 # modules we attempted to autoload
118 my %attempted_to_load;
120 # errors from loading files
121 my %file_load_errors;
123 # what happened when we tried to load
124 my %reader_load_errors;
125 my %writer_load_errors;
127 # library keys that are image file formats
128 my %file_formats = map { $_ => 1 } qw/tiff pnm gif png jpeg raw bmp tga/;
130 # image pixel combine types
132 qw/none normal multiply dissolve add subtract diff lighten darken
133 hue saturation value color/;
135 @combine_types{@combine_types} = 0 .. $#combine_types;
136 $combine_types{mult} = $combine_types{multiply};
137 $combine_types{'sub'} = $combine_types{subtract};
138 $combine_types{sat} = $combine_types{saturation};
140 # this will be used to store global defaults at some point
147 my $ex_version = eval $Exporter::VERSION;
148 if ($ex_version < 5.57) {
149 our @ISA = qw(Exporter);
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",
170 tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
180 for(i_list_formats()) { $formats_low{$_}++; }
182 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
186 # the members of the subhashes under %filters are:
187 # callseq - a list of the parameters to the underlying filter in the
188 # order they are passed
189 # callsub - a code ref that takes a named parameter list and calls the
191 # defaults - a hash of default values
192 # names - defines names for value of given parameters so if the names
193 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
194 # foo parameter, the filter will receive 1 for the foo
197 callseq => ['image','intensity'],
198 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
202 callseq => ['image', 'amount', 'subtype'],
203 defaults => { amount=>3,subtype=>0 },
204 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
207 $filters{hardinvert} ={
208 callseq => ['image'],
210 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
213 $filters{hardinvertall} =
215 callseq => ['image'],
217 callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
220 $filters{autolevels_skew} ={
221 callseq => ['image','lsat','usat','skew'],
222 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
223 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
226 $filters{autolevels} ={
227 callseq => ['image','lsat','usat'],
228 defaults => { lsat=>0.1,usat=>0.1 },
229 callsub => sub { my %hsh=@_; i_autolevels_mono($hsh{image},$hsh{lsat},$hsh{usat}); }
232 $filters{turbnoise} ={
233 callseq => ['image'],
234 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
235 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
238 $filters{radnoise} ={
239 callseq => ['image'],
240 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
241 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
246 callseq => ['image', 'coef'],
251 i_conv($hsh{image},$hsh{coef})
252 or die Imager->_error_as_msg() . "\n";
258 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
259 defaults => { dist => 0 },
263 my @colors = @{$hsh{colors}};
266 i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
270 $filters{nearest_color} =
272 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
277 # make sure the segments are specified with colors
279 for my $color (@{$hsh{colors}}) {
280 my $new_color = _color($color)
281 or die $Imager::ERRSTR."\n";
282 push @colors, $new_color;
285 i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors,
287 or die Imager->_error_as_msg() . "\n";
290 $filters{gaussian} = {
291 callseq => [ 'image', 'stddev' ],
293 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
295 $filters{gaussian2} = {
296 callseq => [ 'image', 'stddevX', 'stddevY' ],
298 callsub => sub { my %hsh = @_; i_gaussian2($hsh{image}, $hsh{stddevX}, $hsh{stddevY}); },
302 callseq => [ qw(image size) ],
303 defaults => { size => 20 },
304 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
308 callseq => [ qw(image bump elevation lightx lighty st) ],
309 defaults => { elevation=>0, st=> 2 },
312 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
313 $hsh{lightx}, $hsh{lighty}, $hsh{st});
316 $filters{bumpmap_complex} =
318 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
335 for my $cname (qw/Ia Il Is/) {
336 my $old = $hsh{$cname};
337 my $new_color = _color($old)
338 or die $Imager::ERRSTR, "\n";
339 $hsh{$cname} = $new_color;
341 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
342 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
343 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
347 $filters{postlevels} =
349 callseq => [ qw(image levels) ],
350 defaults => { levels => 10 },
351 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
353 $filters{watermark} =
355 callseq => [ qw(image wmark tx ty pixdiff) ],
356 defaults => { pixdiff=>10, tx=>0, ty=>0 },
360 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
366 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
368 ftype => { linear => 0,
374 repeat => { none => 0,
389 multiply => 2, mult => 2,
392 subtract => 5, 'sub' => 5,
402 defaults => { ftype => 0, repeat => 0, combine => 0,
403 super_sample => 0, ssample_param => 4,
416 # make sure the segments are specified with colors
418 for my $segment (@{$hsh{segments}}) {
419 my @new_segment = @$segment;
421 $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
422 push @segments, \@new_segment;
425 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
426 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
427 $hsh{ssample_param}, \@segments)
428 or die Imager->_error_as_msg() . "\n";
431 $filters{unsharpmask} =
433 callseq => [ qw(image stddev scale) ],
434 defaults => { stddev=>2.0, scale=>1.0 },
438 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
442 $FORMATGUESS=\&def_guess_type;
452 # NOTE: this might be moved to an import override later on
457 if ($_[$i] eq '-log-stderr') {
465 goto &Exporter::import;
469 Imager->open_log(log => $_[0], level => $_[1]);
474 my %parms=(loglevel=>1,@_);
476 if (exists $parms{'warn_obsolete'}) {
477 $warn_obsolete = $parms{'warn_obsolete'};
481 Imager->open_log(log => $parms{log}, level => $parms{loglevel})
485 if (exists $parms{'t1log'}) {
487 if (Imager::Font::T1::i_init_t1($parms{'t1log'})) {
488 Imager->_set_error(Imager->_error_as_msg);
502 my (%opts) = ( loglevel => 1, @_ );
504 $is_logging = i_init_log($opts{log}, $opts{loglevel});
505 unless ($is_logging) {
506 Imager->_set_error(Imager->_error_as_msg());
510 Imager->log("Imager $VERSION starting\n", 1);
516 i_init_log(undef, -1);
521 my ($class, $message, $level) = @_;
523 defined $level or $level = 1;
525 i_log_entry($message, $level);
535 print "shutdown code\n";
536 # for(keys %instances) { $instances{$_}->DESTROY(); }
537 malloc_state(); # how do decide if this should be used? -- store something from the import
538 print "Imager exiting\n";
542 # Load a filter plugin
550 if ($^O eq 'android') {
552 $filename = File::Spec->rel2abs($filename);
555 my ($DSO_handle,$str)=DSO_open($filename);
556 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
557 my %funcs=DSO_funclist($DSO_handle);
558 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
560 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
562 $DSOs{$filename}=[$DSO_handle,\%funcs];
565 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
566 $DEBUG && print "eval string:\n",$evstr,"\n";
578 if ($^O eq 'android') {
580 $filename = File::Spec->rel2abs($filename);
583 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
584 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
585 for(keys %{$funcref}) {
587 $DEBUG && print "unloading: $_\n";
589 my $rc=DSO_close($DSO_handle);
590 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
594 # take the results of i_error() and make a message out of it
596 return join(": ", map $_->[0], i_errors());
599 # this function tries to DWIM for color parameters
600 # color objects are used as is
601 # simple scalars are simply treated as single parameters to Imager::Color->new
602 # hashrefs are treated as named argument lists to Imager::Color->new
603 # arrayrefs are treated as list arguments to Imager::Color->new iff any
605 # other arrayrefs are treated as list arguments to Imager::Color::Float
609 # perl 5.6.0 seems to do weird things to $arg if we don't make an
610 # explicitly stringified copy
611 # I vaguely remember a bug on this on p5p, but couldn't find it
612 # through bugs.perl.org (I had trouble getting it to find any bugs)
613 my $copy = $arg . "";
617 if (UNIVERSAL::isa($arg, "Imager::Color")
618 || UNIVERSAL::isa($arg, "Imager::Color::Float")) {
622 if ($copy =~ /^HASH\(/) {
623 $result = Imager::Color->new(%$arg);
625 elsif ($copy =~ /^ARRAY\(/) {
626 $result = Imager::Color->new(@$arg);
629 $Imager::ERRSTR = "Not a color";
634 # assume Imager::Color::new knows how to handle it
635 $result = Imager::Color->new($arg);
642 my ($self, $combine, $default) = @_;
644 if (!defined $combine && ref $self) {
645 $combine = $self->{combine};
647 defined $combine or $combine = $defaults{combine};
648 defined $combine or $combine = $default;
650 if (exists $combine_types{$combine}) {
651 $combine = $combine_types{$combine};
658 my ($self, $method) = @_;
661 or return Imager->_set_error("$method needs an image object");
663 $self->{IMG} && Scalar::Util::blessed($self->{IMG}) and return 1;
665 my $msg = $self->{IMG} ? "images do not cross threads" : "empty input image";
666 $msg = "$method: $msg" if $method;
667 $self->_set_error($msg);
672 # returns first defined parameter
675 return $_ if defined $_;
681 # Methods to be called on objects.
684 # Create a new Imager object takes very few parameters.
685 # usually you call this method and then call open from
686 # the resulting object
693 $self->{IMG}=undef; # Just to indicate what exists
694 $self->{ERRSTR}=undef; #
695 $self->{DEBUG}=$DEBUG;
696 $self->{DEBUG} and print "Initialized Imager\n";
697 if (defined $hsh{file} ||
700 defined $hsh{callback} ||
701 defined $hsh{readcb} ||
702 defined $hsh{data} ||
704 # allow $img = Imager->new(file => $filename)
707 # type is already used as a parameter to new(), rename it for the
709 if ($hsh{filetype}) {
710 $extras{type} = $hsh{filetype};
712 unless ($self->read(%hsh, %extras)) {
713 $Imager::ERRSTR = $self->{ERRSTR};
717 elsif (defined $hsh{xsize} || defined $hsh{ysize}) {
718 unless ($self->img_set(%hsh)) {
719 $Imager::ERRSTR = $self->{ERRSTR};
724 Imager->_set_error("new: supply xsize and ysize or a file access parameter or no parameters");
731 # Copy an entire image with no changes
732 # - if an image has magic the copy of it will not be magical
737 $self->_valid_image("copy")
740 unless (defined wantarray) {
742 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
746 my $newcopy=Imager->new();
747 $newcopy->{IMG} = i_copy($self->{IMG});
756 $self->_valid_image("paste")
759 my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
760 my $src = $input{img} || $input{src};
762 $self->_set_error("no source image");
765 unless ($src->_valid_image("paste")) {
766 $self->{ERRSTR} = $src->{ERRSTR} . " (for src)";
769 $input{left}=0 if $input{left} <= 0;
770 $input{top}=0 if $input{top} <= 0;
772 my($r,$b)=i_img_info($src->{IMG});
773 my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
774 my ($src_right, $src_bottom);
775 if ($input{src_coords}) {
776 ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
779 if (defined $input{src_maxx}) {
780 $src_right = $input{src_maxx};
782 elsif (defined $input{width}) {
783 if ($input{width} <= 0) {
784 $self->_set_error("paste: width must me positive");
787 $src_right = $src_left + $input{width};
792 if (defined $input{src_maxy}) {
793 $src_bottom = $input{src_maxy};
795 elsif (defined $input{height}) {
796 if ($input{height} < 0) {
797 $self->_set_error("paste: height must be positive");
800 $src_bottom = $src_top + $input{height};
807 $src_right > $r and $src_right = $r;
808 $src_bottom > $b and $src_bottom = $b;
810 if ($src_right <= $src_left
811 || $src_bottom < $src_top) {
812 $self->_set_error("nothing to paste");
816 i_copyto($self->{IMG}, $src->{IMG},
817 $src_left, $src_top, $src_right, $src_bottom,
818 $input{left}, $input{top});
820 return $self; # What should go here??
823 # Crop an image - i.e. return a new image that is smaller
828 $self->_valid_image("crop")
831 unless (defined wantarray) {
833 warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
839 my ($w, $h, $l, $r, $b, $t) =
840 @hsh{qw(width height left right bottom top)};
842 # work through the various possibilities
847 elsif (!defined $r) {
848 $r = $self->getwidth;
860 $l = int(0.5+($self->getwidth()-$w)/2);
865 $r = $self->getwidth;
871 elsif (!defined $b) {
872 $b = $self->getheight;
884 $t=int(0.5+($self->getheight()-$h)/2);
889 $b = $self->getheight;
892 ($l,$r)=($r,$l) if $l>$r;
893 ($t,$b)=($b,$t) if $t>$b;
896 $r > $self->getwidth and $r = $self->getwidth;
898 $b > $self->getheight and $b = $self->getheight;
900 if ($l == $r || $t == $b) {
901 $self->_set_error("resulting image would have no content");
904 if( $r < $l or $b < $t ) {
905 $self->_set_error("attempting to crop outside of the image");
908 my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
910 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
915 my ($self, %opts) = @_;
920 my $x = $opts{xsize} || $self->getwidth;
921 my $y = $opts{ysize} || $self->getheight;
922 my $channels = $opts{channels} || $self->getchannels;
924 my $out = Imager->new;
925 if ($channels == $self->getchannels) {
926 $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
929 $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
931 unless ($out->{IMG}) {
932 $self->{ERRSTR} = $self->_error_as_msg;
939 # Sets an image to a certain size and channel number
940 # if there was previously data in the image it is discarded
953 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
958 if (my $channels = $model_channels{$hsh{model}}) {
959 $hsh{channels} = $channels;
962 $self->_set_error("new: unknown value for model '$hsh{model}'");
967 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
968 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
969 $hsh{maxcolors} || 256);
971 elsif ($hsh{bits} eq 'double') {
972 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
974 elsif ($hsh{bits} == 16) {
975 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
978 $self->{IMG}= i_img_8_new($hsh{'xsize'}, $hsh{'ysize'},
982 unless ($self->{IMG}) {
983 $self->_set_error(Imager->_error_as_msg());
990 # created a masked version of the current image
994 $self->_valid_image("masked")
997 my %opts = (left => 0,
999 right => $self->getwidth,
1000 bottom => $self->getheight,
1002 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
1004 my $result = Imager->new;
1005 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
1006 $opts{top}, $opts{right} - $opts{left},
1007 $opts{bottom} - $opts{top});
1008 unless ($result->{IMG}) {
1009 $self->_set_error(Imager->_error_as_msg);
1013 # keep references to the mask and base images so they don't
1015 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
1020 # convert an RGB image into a paletted image
1024 if (@_ != 1 && !ref $_[0]) {
1031 unless (defined wantarray) {
1032 my @caller = caller;
1033 warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
1037 $self->_valid_image("to_paletted")
1040 my $result = Imager->new;
1041 unless ($result->{IMG} = i_img_to_pal($self->{IMG}, $opts)) {
1042 $self->_set_error(Imager->_error_as_msg);
1050 my ($class, $quant, @images) = @_;
1053 Imager->_set_error("make_palette: supply at least one image");
1057 for my $img (@images) {
1058 unless ($img->{IMG}) {
1059 Imager->_set_error("make_palette: image $index is empty");
1065 my @cols = i_img_make_palette($quant, map $_->{IMG}, @images);
1067 Imager->_set_error(Imager->_error_as_msg);
1073 # convert a paletted (or any image) to an 8-bit/channel RGB image
1077 unless (defined wantarray) {
1078 my @caller = caller;
1079 warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
1083 $self->_valid_image("to_rgb8")
1086 my $result = Imager->new;
1087 unless ($result->{IMG} = i_img_to_rgb($self->{IMG})) {
1088 $self->_set_error(Imager->_error_as_msg());
1095 # convert a paletted (or any image) to a 16-bit/channel RGB image
1099 unless (defined wantarray) {
1100 my @caller = caller;
1101 warn "to_rgb16() called in void context - to_rgb16() returns the converted image at $caller[1] line $caller[2]\n";
1105 $self->_valid_image("to_rgb16")
1108 my $result = Imager->new;
1109 unless ($result->{IMG} = i_img_to_rgb16($self->{IMG})) {
1110 $self->_set_error(Imager->_error_as_msg());
1117 # convert a paletted (or any image) to an double/channel RGB image
1121 unless (defined wantarray) {
1122 my @caller = caller;
1123 warn "to_rgb16() called in void context - to_rgb_double() returns the converted image at $caller[1] line $caller[2]\n";
1127 $self->_valid_image("to_rgb_double")
1130 my $result = Imager->new;
1131 unless ($result->{IMG} = i_img_to_drgb($self->{IMG})) {
1132 $self->_set_error(Imager->_error_as_msg());
1141 my %opts = (colors=>[], @_);
1143 $self->_valid_image("addcolors")
1146 my @colors = @{$opts{colors}}
1149 for my $color (@colors) {
1150 $color = _color($color);
1152 $self->_set_error($Imager::ERRSTR);
1157 return i_addcolors($self->{IMG}, @colors);
1162 my %opts = (start=>0, colors=>[], @_);
1164 $self->_valid_image("setcolors")
1167 my @colors = @{$opts{colors}}
1170 for my $color (@colors) {
1171 $color = _color($color);
1173 $self->_set_error($Imager::ERRSTR);
1178 return i_setcolors($self->{IMG}, $opts{start}, @colors);
1185 $self->_valid_image("getcolors")
1188 if (!exists $opts{start} && !exists $opts{count}) {
1191 $opts{count} = $self->colorcount;
1193 elsif (!exists $opts{count}) {
1196 elsif (!exists $opts{start}) {
1200 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
1206 $self->_valid_image("colorcount")
1209 return i_colorcount($self->{IMG});
1215 $self->_valid_image("maxcolors")
1218 i_maxcolors($self->{IMG});
1225 $self->_valid_image("findcolor")
1228 unless ($opts{color}) {
1229 $self->_set_error("findcolor: no color parameter");
1233 my $color = _color($opts{color})
1236 return i_findcolor($self->{IMG}, $color);
1242 $self->_valid_image("bits")
1245 my $bits = i_img_bits($self->{IMG});
1246 if ($bits && $bits == length(pack("d", 1)) * 8) {
1255 $self->_valid_image("type")
1258 return i_img_type($self->{IMG}) ? "paletted" : "direct";
1264 $self->_valid_image("virtual")
1267 return i_img_virtual($self->{IMG});
1273 $self->_valid_image("is_bilevel")
1276 return i_img_is_monochrome($self->{IMG});
1280 my ($self, %opts) = @_;
1282 $self->_valid_image("tags")
1285 if (defined $opts{name}) {
1289 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
1290 push @result, (i_tags_get($self->{IMG}, $found))[1];
1293 return wantarray ? @result : $result[0];
1295 elsif (defined $opts{code}) {
1299 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
1300 push @result, (i_tags_get($self->{IMG}, $found))[1];
1307 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
1310 return i_tags_count($self->{IMG});
1319 $self->_valid_image("addtag")
1323 if (defined $opts{value}) {
1324 if ($opts{value} =~ /^\d+$/) {
1326 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
1329 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
1332 elsif (defined $opts{data}) {
1333 # force addition as a string
1334 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
1337 $self->{ERRSTR} = "No value supplied";
1341 elsif ($opts{code}) {
1342 if (defined $opts{value}) {
1343 if ($opts{value} =~ /^\d+$/) {
1345 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
1348 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
1351 elsif (defined $opts{data}) {
1352 # force addition as a string
1353 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
1356 $self->{ERRSTR} = "No value supplied";
1369 $self->_valid_image("deltag")
1372 if (defined $opts{'index'}) {
1373 return i_tags_delete($self->{IMG}, $opts{'index'});
1375 elsif (defined $opts{name}) {
1376 return i_tags_delbyname($self->{IMG}, $opts{name});
1378 elsif (defined $opts{code}) {
1379 return i_tags_delbycode($self->{IMG}, $opts{code});
1382 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
1388 my ($self, %opts) = @_;
1390 $self->_valid_image("settag")
1394 $self->deltag(name=>$opts{name});
1395 return $self->addtag(name=>$opts{name}, value=>$opts{value});
1397 elsif (defined $opts{code}) {
1398 $self->deltag(code=>$opts{code});
1399 return $self->addtag(code=>$opts{code}, value=>$opts{value});
1407 sub _get_reader_io {
1408 my ($self, $input) = @_;
1411 return $input->{io}, undef;
1413 elsif ($input->{fd}) {
1414 return io_new_fd($input->{fd});
1416 elsif ($input->{fh}) {
1417 unless (Scalar::Util::openhandle($input->{fh})) {
1418 $self->_set_error("Handle in fh option not opened");
1421 return Imager::IO->new_fh($input->{fh});
1423 elsif ($input->{file}) {
1424 my $file = IO::File->new($input->{file}, "r");
1426 $self->_set_error("Could not open $input->{file}: $!");
1430 return (io_new_fd(fileno($file)), $file);
1432 elsif ($input->{data}) {
1433 return io_new_buffer($input->{data});
1435 elsif ($input->{callback} || $input->{readcb}) {
1436 if (!$input->{seekcb}) {
1437 $self->_set_error("Need a seekcb parameter");
1439 if ($input->{maxbuffer}) {
1440 return io_new_cb($input->{writecb},
1441 $input->{callback} || $input->{readcb},
1442 $input->{seekcb}, $input->{closecb},
1443 $input->{maxbuffer});
1446 return io_new_cb($input->{writecb},
1447 $input->{callback} || $input->{readcb},
1448 $input->{seekcb}, $input->{closecb});
1452 $self->_set_error("file/fd/fh/data/callback parameter missing");
1457 sub _get_writer_io {
1458 my ($self, $input) = @_;
1460 my $buffered = exists $input->{buffered} ? $input->{buffered} : 1;
1467 elsif ($input->{fd}) {
1468 $io = io_new_fd($input->{fd});
1470 elsif ($input->{fh}) {
1471 unless (Scalar::Util::openhandle($input->{fh})) {
1472 $self->_set_error("Handle in fh option not opened");
1475 $io = Imager::IO->new_fh($input->{fh});
1477 elsif ($input->{file}) {
1478 my $fh = new IO::File($input->{file},"w+");
1480 $self->_set_error("Could not open file $input->{file}: $!");
1483 binmode($fh) or die;
1484 $io = io_new_fd(fileno($fh));
1487 elsif ($input->{data}) {
1488 $io = io_new_bufchain();
1490 elsif ($input->{callback} || $input->{writecb}) {
1491 if ($input->{maxbuffer} && $input->{maxbuffer} == 1) {
1494 $io = io_new_cb($input->{callback} || $input->{writecb},
1496 $input->{seekcb}, $input->{closecb});
1499 $self->_set_error("file/fd/fh/data/callback parameter missing");
1503 unless ($buffered) {
1504 $io->set_buffered(0);
1507 return ($io, @extras);
1513 return i_test_format_probe($io, -1);
1516 sub add_file_magic {
1517 my ($class, %opts) = @_;
1519 my $name = delete $opts{name};
1520 my $bits = delete $opts{bits};
1521 my $mask = delete $opts{mask};
1523 unless (i_add_file_magic($name, $bits, $mask)) {
1524 Imager->_set_error(Imager->_error_as_msg);
1531 # Read an image from file
1537 if (defined($self->{IMG})) {
1538 # let IIM_DESTROY do the destruction, since the image may be
1539 # referenced from elsewhere
1540 #i_img_destroy($self->{IMG});
1541 undef($self->{IMG});
1544 my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
1546 my $type = $input{'type'};
1548 $type = _test_format($IO);
1551 if ($input{file} && !$type) {
1553 $type = $FORMATGUESS->($input{file});
1557 my $msg = "type parameter missing and it couldn't be determined from the file contents";
1558 $input{file} and $msg .= " or file name";
1559 $self->_set_error($msg);
1563 _reader_autoload($type);
1565 if ($readers{$type} && $readers{$type}{single}) {
1566 return $readers{$type}{single}->($self, $IO, %input);
1569 unless ($formats_low{$type}) {
1570 my $read_types = join ', ', sort Imager->read_types();
1571 $self->_set_error("format '$type' not supported - formats $read_types available for reading - $reader_load_errors{$type}");
1575 my $allow_incomplete = $input{allow_incomplete};
1576 defined $allow_incomplete or $allow_incomplete = 0;
1578 if ( $type eq 'pnm' ) {
1579 $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
1580 if ( !defined($self->{IMG}) ) {
1581 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
1584 $self->{DEBUG} && print "loading a pnm file\n";
1588 if ( $type eq 'bmp' ) {
1589 $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
1590 if ( !defined($self->{IMG}) ) {
1591 $self->{ERRSTR}=$self->_error_as_msg();
1594 $self->{DEBUG} && print "loading a bmp file\n";
1597 if ( $type eq 'tga' ) {
1598 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
1599 if ( !defined($self->{IMG}) ) {
1600 $self->{ERRSTR}=$self->_error_as_msg();
1603 $self->{DEBUG} && print "loading a tga file\n";
1606 if ( $type eq 'raw' ) {
1607 unless ( $input{xsize} && $input{ysize} ) {
1608 $self->_set_error('missing xsize or ysize parameter for raw');
1612 my $interleave = _first($input{raw_interleave}, $input{interleave});
1613 unless (defined $interleave) {
1614 my @caller = caller;
1615 warn "read(type => 'raw') $caller[2] line $caller[1]: supply interleave or raw_interleave for future compatibility\n";
1618 my $data_ch = _first($input{raw_datachannels}, $input{datachannels}, 3);
1619 my $store_ch = _first($input{raw_storechannels}, $input{storechannels}, 3);
1621 $self->{IMG} = i_readraw_wiol( $IO,
1627 if ( !defined($self->{IMG}) ) {
1628 $self->{ERRSTR}=$self->_error_as_msg();
1631 $self->{DEBUG} && print "loading a raw file\n";
1637 sub register_reader {
1638 my ($class, %opts) = @_;
1641 or die "register_reader called with no type parameter\n";
1643 my $type = $opts{type};
1645 defined $opts{single} || defined $opts{multiple}
1646 or die "register_reader called with no single or multiple parameter\n";
1648 $readers{$type} = { };
1649 if ($opts{single}) {
1650 $readers{$type}{single} = $opts{single};
1652 if ($opts{multiple}) {
1653 $readers{$type}{multiple} = $opts{multiple};
1659 sub register_writer {
1660 my ($class, %opts) = @_;
1663 or die "register_writer called with no type parameter\n";
1665 my $type = $opts{type};
1667 defined $opts{single} || defined $opts{multiple}
1668 or die "register_writer called with no single or multiple parameter\n";
1670 $writers{$type} = { };
1671 if ($opts{single}) {
1672 $writers{$type}{single} = $opts{single};
1674 if ($opts{multiple}) {
1675 $writers{$type}{multiple} = $opts{multiple};
1686 grep($file_formats{$_}, keys %formats),
1687 qw(ico sgi), # formats not handled directly, but supplied with Imager
1698 grep($file_formats{$_}, keys %formats),
1699 qw(ico sgi), # formats not handled directly, but supplied with Imager
1706 my ($file, $error) = @_;
1708 if ($attempted_to_load{$file}) {
1709 if ($file_load_errors{$file}) {
1710 $$error = $file_load_errors{$file};
1718 local $SIG{__DIE__};
1721 pop @INC if $INC[-1] eq '.';
1722 ++$attempted_to_load{$file};
1730 my $work = $@ || "Unknown error";
1732 $work =~ s/\n?Compilation failed in require at .*Imager\.pm line .*\z//m;
1733 $work =~ s/\n/\\n/g;
1734 $work =~ s/\s*\.?\z/ loading $file/;
1735 $file_load_errors{$file} = $work;
1742 # probes for an Imager::File::whatever module
1743 sub _reader_autoload {
1746 return if $formats_low{$type} || $readers{$type};
1748 return unless $type =~ /^\w+$/;
1750 my $file = "Imager/File/\U$type\E.pm";
1753 my $loaded = _load_file($file, \$error);
1754 if (!$loaded && $error =~ /^Can't locate /) {
1755 my $filer = "Imager/File/\U$type\EReader.pm";
1756 $loaded = _load_file($filer, \$error);
1757 if ($error =~ /^Can't locate /) {
1758 $error = "Can't locate $file or $filer";
1762 $reader_load_errors{$type} = $error;
1766 # probes for an Imager::File::whatever module
1767 sub _writer_autoload {
1770 return if $formats_low{$type} || $writers{$type};
1772 return unless $type =~ /^\w+$/;
1774 my $file = "Imager/File/\U$type\E.pm";
1777 my $loaded = _load_file($file, \$error);
1778 if (!$loaded && $error =~ /^Can't locate /) {
1779 my $filew = "Imager/File/\U$type\EWriter.pm";
1780 $loaded = _load_file($filew, \$error);
1781 if ($error =~ /^Can't locate /) {
1782 $error = "Can't locate $file or $filew";
1786 $writer_load_errors{$type} = $error;
1790 sub _fix_gif_positions {
1791 my ($opts, $opt, $msg, @imgs) = @_;
1793 my $positions = $opts->{'gif_positions'};
1795 for my $pos (@$positions) {
1796 my ($x, $y) = @$pos;
1797 my $img = $imgs[$index++];
1798 $img->settag(name=>'gif_left', value=>$x);
1799 $img->settag(name=>'gif_top', value=>$y) if defined $y;
1801 $$msg .= "replaced with the gif_left and gif_top tags";
1806 gif_each_palette=>'gif_local_map',
1807 interlace => 'gif_interlace',
1808 gif_delays => 'gif_delay',
1809 gif_positions => \&_fix_gif_positions,
1810 gif_loop_count => 'gif_loop',
1813 # options that should be converted to colors
1814 my %color_opts = map { $_ => 1 } qw/i_background/;
1817 my ($self, $opts, $prefix, @imgs) = @_;
1819 for my $opt (keys %$opts) {
1821 if ($obsolete_opts{$opt}) {
1822 my $new = $obsolete_opts{$opt};
1823 my $msg = "Obsolete option $opt ";
1825 $new->($opts, $opt, \$msg, @imgs);
1828 $msg .= "replaced with the $new tag ";
1831 $msg .= "line ".(caller(2))[2]." of file ".(caller(2))[1];
1832 warn $msg if $warn_obsolete && $^W;
1834 next unless $tagname =~ /^\Q$prefix/;
1835 my $value = $opts->{$opt};
1836 if ($color_opts{$opt}) {
1837 $value = _color($value);
1839 $self->_set_error($Imager::ERRSTR);
1844 if (UNIVERSAL::isa($value, "Imager::Color")) {
1845 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1846 for my $img (@imgs) {
1847 $img->settag(name=>$tagname, value=>$tag);
1850 elsif (ref($value) eq 'ARRAY') {
1851 for my $i (0..$#$value) {
1852 my $val = $value->[$i];
1854 if (UNIVERSAL::isa($val, "Imager::Color")) {
1855 my $tag = sprintf("color(%d,%d,%d,%d)", $value->rgba);
1857 $imgs[$i]->settag(name=>$tagname, value=>$tag);
1860 $self->_set_error("Unknown reference type " . ref($value) .
1861 " supplied in array for $opt");
1867 and $imgs[$i]->settag(name=>$tagname, value=>$val);
1872 $self->_set_error("Unknown reference type " . ref($value) .
1873 " supplied for $opt");
1878 # set it as a tag for every image
1879 for my $img (@imgs) {
1880 $img->settag(name=>$tagname, value=>$value);
1888 # Write an image to file
1891 my %input=(jpegquality=>75,
1901 $self->_valid_image("write")
1904 $self->_set_opts(\%input, "i_", $self)
1907 my $type = $input{'type'};
1908 if (!$type and $input{file}) {
1909 $type = $FORMATGUESS->($input{file});
1912 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1916 _writer_autoload($type);
1919 if ($writers{$type} && $writers{$type}{single}) {
1920 ($IO, $fh) = $self->_get_writer_io(\%input)
1923 $writers{$type}{single}->($self, $IO, %input, type => $type)
1927 if (!$formats_low{$type}) {
1928 my $write_types = join ', ', sort Imager->write_types();
1929 $self->_set_error("format '$type' not supported - formats $write_types available for writing - $writer_load_errors{$type}");
1933 ($IO, $fh) = $self->_get_writer_io(\%input, $type)
1936 if ( $type eq 'pnm' ) {
1937 $self->_set_opts(\%input, "pnm_", $self)
1939 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1940 $self->{ERRSTR} = $self->_error_as_msg();
1943 $self->{DEBUG} && print "writing a pnm file\n";
1945 elsif ( $type eq 'raw' ) {
1946 $self->_set_opts(\%input, "raw_", $self)
1948 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
1949 $self->{ERRSTR} = $self->_error_as_msg();
1952 $self->{DEBUG} && print "writing a raw file\n";
1954 elsif ( $type eq 'bmp' ) {
1955 $self->_set_opts(\%input, "bmp_", $self)
1957 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1958 $self->{ERRSTR} = $self->_error_as_msg;
1961 $self->{DEBUG} && print "writing a bmp file\n";
1963 elsif ( $type eq 'tga' ) {
1964 $self->_set_opts(\%input, "tga_", $self)
1967 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1968 $self->{ERRSTR}=$self->_error_as_msg();
1971 $self->{DEBUG} && print "writing a tga file\n";
1975 if (exists $input{'data'}) {
1976 my $data = io_slurp($IO);
1978 $self->{ERRSTR}='Could not slurp from buffer';
1981 ${$input{data}} = $data;
1987 my ($class, $opts, @images) = @_;
1989 my $type = $opts->{type};
1991 if (!$type && $opts->{'file'}) {
1992 $type = $FORMATGUESS->($opts->{'file'});
1995 $class->_set_error('type parameter missing and not possible to guess from extension');
1998 # translate to ImgRaw
2000 for my $img (@images) {
2001 unless (ref $img && Scalar::Util::blessed($img) && $img->isa("Imager")) {
2002 $class->_set_error("write_multi: image $index is not an Imager image object");
2005 unless ($img->_valid_image("write_multi")) {
2006 $class->_set_error($img->errstr . " (image $index)");
2011 $class->_set_opts($opts, "i_", @images)
2013 my @work = map $_->{IMG}, @images;
2015 _writer_autoload($type);
2018 if ($writers{$type} && $writers{$type}{multiple}) {
2019 ($IO, $file) = $class->_get_writer_io($opts, $type)
2022 $writers{$type}{multiple}->($class, $IO, $opts, @images)
2026 if (!$formats{$type}) {
2027 my $write_types = join ', ', sort Imager->write_types();
2028 $class->_set_error("format '$type' not supported - formats $write_types available for writing");
2032 ($IO, $file) = $class->_get_writer_io($opts, $type)
2035 if (0) { # eventually PNM in here, now that TIFF/GIF are elsewhere
2039 unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
2044 $ERRSTR = "Sorry, write_multi doesn't support $type yet";
2050 if (exists $opts->{'data'}) {
2051 my $data = io_slurp($IO);
2053 Imager->_set_error('Could not slurp from buffer');
2056 ${$opts->{data}} = $data;
2061 # read multiple images from a file
2063 my ($class, %opts) = @_;
2065 my ($IO, $file) = $class->_get_reader_io(\%opts, $opts{'type'})
2068 my $type = $opts{'type'};
2070 $type = _test_format($IO);
2073 if ($opts{file} && !$type) {
2075 $type = $FORMATGUESS->($opts{file});
2079 my $msg = "type parameter missing and it couldn't be determined from the file contents";
2080 $opts{file} and $msg .= " or file name";
2081 Imager->_set_error($msg);
2085 _reader_autoload($type);
2087 if ($readers{$type} && $readers{$type}{multiple}) {
2088 return $readers{$type}{multiple}->($IO, %opts);
2091 unless ($formats{$type}) {
2092 my $read_types = join ', ', sort Imager->read_types();
2093 Imager->_set_error("format '$type' not supported - formats $read_types available for reading");
2098 if ($type eq 'pnm') {
2099 @imgs = i_readpnm_multi_wiol($IO, $opts{allow_incomplete}||0);
2102 my $img = Imager->new;
2103 if ($img->read(%opts, io => $IO, type => $type)) {
2106 Imager->_set_error($img->errstr);
2111 $ERRSTR = _error_as_msg();
2115 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
2119 # Destroy an Imager object
2123 # delete $instances{$self};
2124 if (defined($self->{IMG})) {
2125 # the following is now handled by the XS DESTROY method for
2126 # Imager::ImgRaw object
2127 # Re-enabling this will break virtual images
2128 # tested for in t/t020masked.t
2129 # i_img_destroy($self->{IMG});
2130 undef($self->{IMG});
2132 # print "Destroy Called on an empty image!\n"; # why did I put this here??
2136 # Perform an inplace filter of an image
2137 # that is the image will be overwritten with the data
2144 $self->_valid_image("filter")
2147 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
2149 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
2150 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
2153 if ($filters{$input{'type'}}{names}) {
2154 my $names = $filters{$input{'type'}}{names};
2155 for my $name (keys %$names) {
2156 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
2157 $input{$name} = $names->{$name}{$input{$name}};
2161 if (defined($filters{$input{'type'}}{defaults})) {
2162 %hsh=( image => $self->{IMG},
2164 %{$filters{$input{'type'}}{defaults}},
2167 %hsh=( image => $self->{IMG},
2172 my @cs=@{$filters{$input{'type'}}{callseq}};
2175 if (!defined($hsh{$_})) {
2176 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
2181 local $SIG{__DIE__}; # we don't want this processed by confess, etc
2182 &{$filters{$input{'type'}}{callsub}}(%hsh);
2185 chomp($self->{ERRSTR} = $@);
2191 $self->{DEBUG} && print "callseq is: @cs\n";
2192 $self->{DEBUG} && print "matching callseq is: @b\n";
2197 sub register_filter {
2199 my %hsh = ( defaults => {}, @_ );
2202 or die "register_filter() with no type\n";
2203 defined $hsh{callsub}
2204 or die "register_filter() with no callsub\n";
2205 defined $hsh{callseq}
2206 or die "register_filter() with no callseq\n";
2208 exists $filters{$hsh{type}}
2211 $filters{$hsh{type}} = \%hsh;
2216 sub scale_calculate {
2219 my %opts = ('type'=>'max', @_);
2221 # none of these should be references
2222 for my $name (qw/xpixels ypixels xscalefactor yscalefactor width height/) {
2223 if (defined $opts{$name} && ref $opts{$name}) {
2224 $self->_set_error("scale_calculate: $name parameter cannot be a reference");
2229 my ($x_scale, $y_scale);
2230 my $width = $opts{width};
2231 my $height = $opts{height};
2233 defined $width or $width = $self->getwidth;
2234 defined $height or $height = $self->getheight;
2237 unless (defined $width && defined $height) {
2238 $self->_set_error("scale_calculate: width and height parameters must be supplied when called as a class method");
2243 if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
2244 $x_scale = $opts{'xscalefactor'};
2245 $y_scale = $opts{'yscalefactor'};
2247 elsif ($opts{'xscalefactor'}) {
2248 $x_scale = $opts{'xscalefactor'};
2249 $y_scale = $opts{'scalefactor'} || $x_scale;
2251 elsif ($opts{'yscalefactor'}) {
2252 $y_scale = $opts{'yscalefactor'};
2253 $x_scale = $opts{'scalefactor'} || $y_scale;
2256 $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
2259 # work out the scaling
2260 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
2261 my ($xpix, $ypix)=( $opts{xpixels} / $width ,
2262 $opts{ypixels} / $height );
2263 if ($opts{'type'} eq 'min') {
2264 $x_scale = $y_scale = _min($xpix,$ypix);
2266 elsif ($opts{'type'} eq 'max') {
2267 $x_scale = $y_scale = _max($xpix,$ypix);
2269 elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
2274 $self->_set_error('invalid value for type parameter');
2277 } elsif ($opts{xpixels}) {
2278 $x_scale = $y_scale = $opts{xpixels} / $width;
2280 elsif ($opts{ypixels}) {
2281 $x_scale = $y_scale = $opts{ypixels}/$height;
2283 elsif ($opts{constrain} && ref $opts{constrain}
2284 && $opts{constrain}->can('constrain')) {
2285 # we've been passed an Image::Math::Constrain object or something
2286 # that looks like one
2288 (undef, undef, $scalefactor)
2289 = $opts{constrain}->constrain($self->getwidth, $self->getheight);
2290 unless ($scalefactor) {
2291 $self->_set_error('constrain method failed on constrain parameter');
2294 $x_scale = $y_scale = $scalefactor;
2297 my $new_width = int($x_scale * $width + 0.5);
2298 $new_width > 0 or $new_width = 1;
2299 my $new_height = int($y_scale * $height + 0.5);
2300 $new_height > 0 or $new_height = 1;
2302 return ($x_scale, $y_scale, $new_width, $new_height);
2306 # Scale an image to requested size and return the scaled version
2310 my %opts = (qtype=>'normal' ,@_);
2311 my $img = Imager->new();
2312 my $tmp = Imager->new();
2314 unless (defined wantarray) {
2315 my @caller = caller;
2316 warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
2320 $self->_valid_image("scale")
2323 my ($x_scale, $y_scale, $new_width, $new_height) =
2324 $self->scale_calculate(%opts)
2327 if ($opts{qtype} eq 'normal') {
2328 $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
2329 if ( !defined($tmp->{IMG}) ) {
2330 $self->{ERRSTR} = 'unable to scale image: ' . $self->_error_as_msg;
2333 $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
2334 if ( !defined($img->{IMG}) ) {
2335 $self->{ERRSTR}='unable to scale image: ' . $self->_error_as_msg;
2341 elsif ($opts{'qtype'} eq 'preview') {
2342 $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
2343 if ( !defined($img->{IMG}) ) {
2344 $self->{ERRSTR}='unable to scale image';
2349 elsif ($opts{'qtype'} eq 'mixing') {
2350 $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
2351 unless ($img->{IMG}) {
2352 $self->_set_error(Imager->_error_as_msg);
2358 $self->_set_error('invalid value for qtype parameter');
2363 # Scales only along the X axis
2367 my %opts = ( scalefactor=>0.5, @_ );
2369 unless (defined wantarray) {
2370 my @caller = caller;
2371 warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
2375 $self->_valid_image("scaleX")
2378 my $img = Imager->new();
2380 my $scalefactor = $opts{scalefactor};
2382 if ($opts{pixels}) {
2383 $scalefactor = $opts{pixels} / $self->getwidth();
2386 unless ($self->{IMG}) {
2387 $self->{ERRSTR}='empty input image';
2391 $img->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
2393 if ( !defined($img->{IMG}) ) {
2394 $self->{ERRSTR} = 'unable to scale image';
2401 # Scales only along the Y axis
2405 my %opts = ( scalefactor => 0.5, @_ );
2407 unless (defined wantarray) {
2408 my @caller = caller;
2409 warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
2413 $self->_valid_image("scaleY")
2416 my $img = Imager->new();
2418 my $scalefactor = $opts{scalefactor};
2420 if ($opts{pixels}) {
2421 $scalefactor = $opts{pixels} / $self->getheight();
2424 unless ($self->{IMG}) {
2425 $self->{ERRSTR} = 'empty input image';
2428 $img->{IMG}=i_scaleaxis($self->{IMG}, $scalefactor, 1);
2430 if ( !defined($img->{IMG}) ) {
2431 $self->{ERRSTR} = 'unable to scale image';
2438 # Transform returns a spatial transformation of the input image
2439 # this moves pixels to a new location in the returned image.
2440 # NOTE - should make a utility function to check transforms for
2448 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
2450 # print Dumper(\%opts);
2453 $self->_valid_image("transform")
2456 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
2460 pop @INC if $INC[-1] eq '.';
2461 eval ("use Affix::Infix2Postfix;");
2465 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
2468 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
2469 {op=>'-',trans=>'Sub'},
2470 {op=>'*',trans=>'Mult'},
2471 {op=>'/',trans=>'Div'},
2472 {op=>'-','type'=>'unary',trans=>'u-'},
2474 {op=>'func','type'=>'unary'}],
2475 'grouping'=>[qw( \( \) )],
2476 'func'=>[qw( sin cos )],
2481 @xt=$I2P->translate($opts{'xexpr'});
2482 @yt=$I2P->translate($opts{'yexpr'});
2484 $numre=$I2P->{'numre'};
2487 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
2488 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
2489 @{$opts{'parm'}}=@pt;
2492 # print Dumper(\%opts);
2494 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
2495 $self->{ERRSTR}='transform: no xopcodes given.';
2499 @op=@{$opts{'xopcodes'}};
2501 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2502 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2505 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2511 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
2512 $self->{ERRSTR}='transform: no yopcodes given.';
2516 @op=@{$opts{'yopcodes'}};
2518 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
2519 $self->{ERRSTR}="transform: illegal opcode '$_'.";
2522 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
2527 if ( !exists $opts{'parm'}) {
2528 $self->{ERRSTR}='transform: no parameter arg given.';
2532 # print Dumper(\@ropx);
2533 # print Dumper(\@ropy);
2534 # print Dumper(\@ropy);
2536 my $img = Imager->new();
2537 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
2538 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
2544 my ($opts, @imgs) = @_;
2546 require "Imager/Expr.pm";
2548 $opts->{variables} = [ qw(x y) ];
2549 my ($width, $height) = @{$opts}{qw(width height)};
2552 for my $img (@imgs) {
2553 unless ($img->_valid_image("transform2")) {
2554 Imager->_set_error($img->errstr . " (input image $index)");
2560 $width ||= $imgs[0]->getwidth();
2561 $height ||= $imgs[0]->getheight();
2563 for my $img (@imgs) {
2564 $opts->{constants}{"w$img_num"} = $img->getwidth();
2565 $opts->{constants}{"h$img_num"} = $img->getheight();
2566 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
2567 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
2572 $opts->{constants}{w} = $width;
2573 $opts->{constants}{cx} = $width/2;
2576 $Imager::ERRSTR = "No width supplied";
2580 $opts->{constants}{h} = $height;
2581 $opts->{constants}{cy} = $height/2;
2584 $Imager::ERRSTR = "No height supplied";
2587 my $code = Imager::Expr->new($opts);
2589 $Imager::ERRSTR = Imager::Expr::error();
2592 my $channels = $opts->{channels} || 3;
2593 unless ($channels >= 1 && $channels <= 4) {
2594 return Imager->_set_error("channels must be an integer between 1 and 4");
2597 my $img = Imager->new();
2598 $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
2599 $channels, $code->code(),
2600 $code->nregs(), $code->cregs(),
2601 [ map { $_->{IMG} } @imgs ]);
2602 if (!defined $img->{IMG}) {
2603 $Imager::ERRSTR = Imager->_error_as_msg();
2614 $self->_valid_image("rubthrough")
2617 unless ($opts{src} && $opts{src}->_valid_image("rubthrough")) {
2618 $self->{ERRSTR} = $opts{src}{ERRSTR} . ' (for src)';
2622 %opts = (src_minx => 0,
2624 src_maxx => $opts{src}->getwidth(),
2625 src_maxy => $opts{src}->getheight(),
2629 defined $tx or $tx = $opts{left};
2630 defined $tx or $tx = 0;
2633 defined $ty or $ty = $opts{top};
2634 defined $ty or $ty = 0;
2636 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $tx, $ty,
2637 $opts{src_minx}, $opts{src_miny},
2638 $opts{src_maxx}, $opts{src_maxy})) {
2639 $self->_set_error($self->_error_as_msg());
2656 $self->_valid_image("compose")
2659 unless ($opts{src}) {
2660 $self->_set_error("compose: src parameter missing");
2664 unless ($opts{src}->_valid_image("compose")) {
2665 $self->_set_error($opts{src}->errstr . " (for src)");
2668 my $src = $opts{src};
2670 my $left = $opts{left};
2671 defined $left or $left = $opts{tx};
2672 defined $left or $left = 0;
2674 my $top = $opts{top};
2675 defined $top or $top = $opts{ty};
2676 defined $top or $top = 0;
2678 my $src_left = $opts{src_left};
2679 defined $src_left or $src_left = $opts{src_minx};
2680 defined $src_left or $src_left = 0;
2682 my $src_top = $opts{src_top};
2683 defined $src_top or $src_top = $opts{src_miny};
2684 defined $src_top or $src_top = 0;
2686 my $width = $opts{width};
2687 if (!defined $width && defined $opts{src_maxx}) {
2688 $width = $opts{src_maxx} - $src_left;
2690 defined $width or $width = $src->getwidth() - $src_left;
2692 my $height = $opts{height};
2693 if (!defined $height && defined $opts{src_maxy}) {
2694 $height = $opts{src_maxy} - $src_top;
2696 defined $height or $height = $src->getheight() - $src_top;
2698 my $combine = $self->_combine($opts{combine}, 'normal');
2701 unless ($opts{mask}->_valid_image("compose")) {
2702 $self->_set_error($opts{mask}->errstr . " (for mask)");
2706 my $mask_left = $opts{mask_left};
2707 defined $mask_left or $mask_left = $opts{mask_minx};
2708 defined $mask_left or $mask_left = 0;
2710 my $mask_top = $opts{mask_top};
2711 defined $mask_top or $mask_top = $opts{mask_miny};
2712 defined $mask_top or $mask_top = 0;
2714 unless (i_compose_mask($self->{IMG}, $src->{IMG}, $opts{mask}{IMG},
2715 $left, $top, $src_left, $src_top,
2716 $mask_left, $mask_top, $width, $height,
2717 $combine, $opts{opacity})) {
2718 $self->_set_error(Imager->_error_as_msg);
2723 unless (i_compose($self->{IMG}, $src->{IMG}, $left, $top, $src_left, $src_top,
2724 $width, $height, $combine, $opts{opacity})) {
2725 $self->_set_error(Imager->_error_as_msg);
2737 $self->_valid_image("flip")
2740 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
2742 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
2743 $dir = $xlate{$opts{'dir'}};
2744 return $self if i_flipxy($self->{IMG}, $dir);
2752 unless (defined wantarray) {
2753 my @caller = caller;
2754 warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
2758 $self->_valid_image("rotate")
2761 if (defined $opts{right}) {
2762 my $degrees = $opts{right};
2764 $degrees += 360 * int(((-$degrees)+360)/360);
2766 $degrees = $degrees % 360;
2767 if ($degrees == 0) {
2768 return $self->copy();
2770 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
2771 my $result = Imager->new();
2772 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
2776 $self->{ERRSTR} = $self->_error_as_msg();
2781 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
2785 elsif (defined $opts{radians} || defined $opts{degrees}) {
2786 my $amount = $opts{radians} || $opts{degrees} * 3.14159265358979 / 180;
2788 my $back = $opts{back};
2789 my $result = Imager->new;
2791 $back = _color($back);
2793 $self->_set_error(Imager->errstr);
2797 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $back);
2800 $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
2802 if ($result->{IMG}) {
2806 $self->{ERRSTR} = $self->_error_as_msg();
2811 $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
2816 sub matrix_transform {
2820 $self->_valid_image("matrix_transform")
2823 unless (defined wantarray) {
2824 my @caller = caller;
2825 warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
2829 if ($opts{matrix}) {
2830 my $xsize = $opts{xsize} || $self->getwidth;
2831 my $ysize = $opts{ysize} || $self->getheight;
2833 my $result = Imager->new;
2835 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2836 $opts{matrix}, $opts{back})
2840 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
2848 $self->{ERRSTR} = "matrix parameter required";
2854 *yatf = \&matrix_transform;
2856 # These two are supported for legacy code only
2859 return Imager::Color->new(@_);
2863 return Imager::Color::set(@_);
2866 # Draws a box between the specified corner points.
2869 my $raw = $self->{IMG};
2871 $self->_valid_image("box")
2876 my ($xmin, $ymin, $xmax, $ymax);
2877 if (exists $opts{'box'}) {
2878 $xmin = _min($opts{'box'}->[0],$opts{'box'}->[2]);
2879 $xmax = _max($opts{'box'}->[0],$opts{'box'}->[2]);
2880 $ymin = _min($opts{'box'}->[1],$opts{'box'}->[3]);
2881 $ymax = _max($opts{'box'}->[1],$opts{'box'}->[3]);
2884 defined($xmin = $opts{xmin}) or $xmin = 0;
2885 defined($xmax = $opts{xmax}) or $xmax = $self->getwidth()-1;
2886 defined($ymin = $opts{ymin}) or $ymin = 0;
2887 defined($ymax = $opts{ymax}) or $ymax = $self->getheight()-1;
2890 if ($opts{filled}) {
2891 my $color = $opts{'color'};
2893 if (defined $color) {
2894 unless (_is_color_object($color)) {
2895 $color = _color($color);
2897 $self->{ERRSTR} = $Imager::ERRSTR;
2903 $color = i_color_new(255,255,255,255);
2906 if ($color->isa("Imager::Color")) {
2907 i_box_filled($raw, $xmin, $ymin,$xmax, $ymax, $color);
2910 i_box_filledf($raw, $xmin, $ymin,$xmax, $ymax, $color);
2913 elsif ($opts{fill}) {
2914 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2915 # assume it's a hash ref
2916 require 'Imager/Fill.pm';
2917 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2918 $self->{ERRSTR} = $Imager::ERRSTR;
2922 i_box_cfill($raw, $xmin, $ymin, $xmax, $ymax, $opts{fill}{fill});
2925 my $color = $opts{'color'};
2926 if (defined $color) {
2927 unless (_is_color_object($color)) {
2928 $color = _color($color);
2930 $self->{ERRSTR} = $Imager::ERRSTR;
2936 $color = i_color_new(255, 255, 255, 255);
2939 $self->{ERRSTR} = $Imager::ERRSTR;
2942 i_box($raw, $xmin, $ymin, $xmax, $ymax, $color);
2951 $self->_valid_image("arc")
2954 my $dflcl= [ 255, 255, 255, 255];
2959 'r'=>_min($self->getwidth(),$self->getheight())/3,
2960 'x'=>$self->getwidth()/2,
2961 'y'=>$self->getheight()/2,
2968 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
2969 # assume it's a hash ref
2970 require 'Imager/Fill.pm';
2971 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
2972 $self->{ERRSTR} = $Imager::ERRSTR;
2976 if ($opts{d1} == 0 && $opts{d2} == 361) {
2977 i_circle_aa_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2981 i_arc_aa_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
2982 $opts{'d2'}, $opts{fill}{fill});
2985 elsif ($opts{filled}) {
2986 my $color = _color($opts{'color'});
2988 $self->{ERRSTR} = $Imager::ERRSTR;
2991 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
2992 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
2996 i_arc_aa($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
2997 $opts{'d1'}, $opts{'d2'}, $color);
3001 my $color = _color($opts{'color'});
3002 if ($opts{d2} - $opts{d1} >= 360) {
3003 $good = i_circle_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $color);
3006 $good = i_arc_out_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'}, $opts{'d1'}, $opts{'d2'}, $color);
3012 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3013 # assume it's a hash ref
3014 require 'Imager/Fill.pm';
3015 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3016 $self->{ERRSTR} = $Imager::ERRSTR;
3020 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
3021 $opts{'d2'}, $opts{fill}{fill});
3024 my $color = _color($opts{'color'});
3026 $self->{ERRSTR} = $Imager::ERRSTR;
3029 if ($opts{filled}) {
3030 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},
3031 $opts{'d1'}, $opts{'d2'}, $color);
3034 if ($opts{d1} == 0 && $opts{d2} == 361) {
3035 $good = i_circle_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $color);
3038 $good = i_arc_out($self->{IMG}, $opts{x}, $opts{y}, $opts{r}, $opts{d1}, $opts{d2}, $color);
3044 $self->_set_error($self->_error_as_msg);
3051 # Draws a line from one point to the other
3052 # the endpoint is set if the endp parameter is set which it is by default.
3053 # to turn of the endpoint being set use endp=>0 when calling line.
3057 my $dflcl=i_color_new(0,0,0,0);
3058 my %opts=(color=>$dflcl,
3062 $self->_valid_image("line")
3065 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
3066 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
3068 my $color = _color($opts{'color'});
3070 $self->{ERRSTR} = $Imager::ERRSTR;
3074 $opts{antialias} = $opts{aa} if defined $opts{aa};
3075 if ($opts{antialias}) {
3076 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
3077 $color, $opts{endp});
3079 i_line($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2},
3080 $color, $opts{endp});
3085 # Draws a line between an ordered set of points - It more or less just transforms this
3086 # into a list of lines.
3090 my ($pt,$ls,@points);
3091 my $dflcl=i_color_new(0,0,0,0);
3092 my %opts=(color=>$dflcl,@_);
3094 $self->_valid_image("polyline")
3097 if (exists($opts{points})) { @points=@{$opts{points}}; }
3098 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
3099 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
3102 # print Dumper(\@points);
3104 my $color = _color($opts{'color'});
3106 $self->{ERRSTR} = $Imager::ERRSTR;
3109 $opts{antialias} = $opts{aa} if defined $opts{aa};
3110 if ($opts{antialias}) {
3113 i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color, 1);
3120 i_line($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$color,1);
3130 my ($pt,$ls,@points);
3131 my $dflcl = i_color_new(0,0,0,0);
3132 my %opts = (color=>$dflcl, @_);
3134 $self->_valid_image("polygon")
3137 if (exists($opts{points})) {
3138 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
3139 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
3142 if (!exists $opts{'x'} or !exists $opts{'y'}) {
3143 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
3146 my $mode = _first($opts{mode}, 0);
3148 if ($opts{'fill'}) {
3149 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
3150 # assume it's a hash ref
3151 require 'Imager/Fill.pm';
3152 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
3153 $self->{ERRSTR} = $Imager::ERRSTR;
3157 unless (i_poly_aa_cfill_m($self->{IMG}, $opts{'x'}, $opts{'y'},
3158 $mode, $opts{'fill'}{'fill'})) {
3159 return $self->_set_error($self->_error_as_msg);
3163 my $color = _color($opts{'color'});
3165 $self->{ERRSTR} = $Imager::ERRSTR;
3168 unless (i_poly_aa_m($self->{IMG}, $opts{'x'}, $opts{'y'}, $mode, $color)) {
3169 return $self->_set_error($self->_error_as_msg);
3177 my ($self, %opts) = @_;
3179 $self->_valid_image("polypolygon")
3182 my $points = $opts{points};
3184 or return $self->_set_error("polypolygon: missing required points");
3186 my $mode = _first($opts{mode}, "evenodd");
3188 if ($opts{filled}) {
3189 my $color = _color(_first($opts{color}, [ 0, 0, 0, 0 ]))
3190 or return $self->_set_error($Imager::ERRSTR);
3192 i_poly_poly_aa($self->{IMG}, $points, $mode, $color)
3193 or return $self->_set_error($self->_error_as_msg);
3195 elsif ($opts{fill}) {
3196 my $fill = $opts{fill};
3197 $self->_valid_fill($fill, "polypolygon")
3200 i_poly_poly_aa_cfill($self->{IMG}, $points, $mode, $fill->{fill})
3201 or return $self->_set_error($self->_error_as_msg);
3204 my $color = _color(_first($opts{color}, [ 0, 0, 0, 255 ]))
3205 or return $self->_set_error($Imager::ERRSTR);
3207 my $rimg = $self->{IMG};
3209 if (_first($opts{aa}, 1)) {
3210 for my $poly (@$points) {
3211 my $xp = $poly->[0];
3212 my $yp = $poly->[1];
3213 for my $i (0 .. $#$xp - 1) {
3214 i_line_aa($rimg, $xp->[$i], $yp->[$i], $xp->[$i+1], $yp->[$i+1],
3217 i_line_aa($rimg, $xp->[$#$xp], $yp->[$#$yp], $xp->[0], $yp->[0],
3222 for my $poly (@$points) {
3223 my $xp = $poly->[0];
3224 my $yp = $poly->[1];
3225 for my $i (0 .. $#$xp - 1) {
3226 i_line($rimg, $xp->[$i], $yp->[$i], $xp->[$i+1], $yp->[$i+1],
3229 i_line($rimg, $xp->[$#$xp], $yp->[$#$yp], $xp->[0], $yp->[0],
3238 # this the multipoint bezier curve
3239 # this is here more for testing that actual usage since
3240 # this is not a good algorithm. Usually the curve would be
3241 # broken into smaller segments and each done individually.
3245 my ($pt,$ls,@points);
3246 my $dflcl=i_color_new(0,0,0,0);
3247 my %opts=(color=>$dflcl,@_);
3249 $self->_valid_image("polybezier")
3252 if (exists $opts{points}) {
3253 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
3254 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
3257 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
3258 $self->{ERRSTR}='Missing or invalid points.';
3262 my $color = _color($opts{'color'});
3264 $self->{ERRSTR} = $Imager::ERRSTR;
3267 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$color);
3273 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
3276 $self->_valid_image("flood_fill")
3279 unless (exists $opts{'x'} && exists $opts{'y'}) {
3280 $self->{ERRSTR} = "missing seed x and y parameters";
3284 if ($opts{border}) {
3285 my $border = _color($opts{border});
3287 $self->_set_error($Imager::ERRSTR);
3291 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3292 # assume it's a hash ref
3293 require Imager::Fill;
3294 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3295 $self->{ERRSTR} = $Imager::ERRSTR;
3299 $rc = i_flood_cfill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3300 $opts{fill}{fill}, $border);
3303 my $color = _color($opts{'color'});
3305 $self->{ERRSTR} = $Imager::ERRSTR;
3308 $rc = i_flood_fill_border($self->{IMG}, $opts{'x'}, $opts{'y'},
3315 $self->{ERRSTR} = $self->_error_as_msg();
3321 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
3322 # assume it's a hash ref
3323 require 'Imager/Fill.pm';
3324 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
3325 $self->{ERRSTR} = $Imager::ERRSTR;
3329 $rc = i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
3332 my $color = _color($opts{'color'});
3334 $self->{ERRSTR} = $Imager::ERRSTR;
3337 $rc = i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $color);
3343 $self->{ERRSTR} = $self->_error_as_msg();
3350 my ($self, %opts) = @_;
3352 $self->_valid_image("setpixel")
3355 my $color = $opts{color};
3356 unless (defined $color) {
3357 $color = $self->{fg};
3358 defined $color or $color = NC(255, 255, 255);
3361 unless (ref $color && UNIVERSAL::isa($color, "Imager::Color")) {
3362 unless ($color = _color($color, 'setpixel')) {
3363 $self->_set_error("setpixel: " . Imager->errstr);
3368 unless (exists $opts{'x'} && exists $opts{'y'}) {
3369 $self->_set_error('setpixel: missing x or y parameter');
3375 if (ref $x || ref $y) {
3376 $x = ref $x ? $x : [ $x ];
3377 $y = ref $y ? $y : [ $y ];
3379 $self->_set_error("setpixel: x is a reference to an empty array");
3383 $self->_set_error("setpixel: y is a reference to an empty array");
3387 # make both the same length, replicating the last element
3389 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3392 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3396 if ($color->isa('Imager::Color')) {
3397 for my $i (0..$#$x) {
3398 i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
3403 for my $i (0..$#$x) {
3404 i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
3412 if ($color->isa('Imager::Color')) {
3413 i_ppix($self->{IMG}, $x, $y, $color)
3414 and return "0 but true";
3417 i_ppixf($self->{IMG}, $x, $y, $color)
3418 and return "0 but true";
3428 my %opts = ( "type"=>'8bit', @_);
3430 $self->_valid_image("getpixel")
3433 unless (exists $opts{'x'} && exists $opts{'y'}) {
3434 $self->_set_error('getpixel: missing x or y parameter');
3440 my $type = $opts{'type'};
3441 if (ref $x || ref $y) {
3442 $x = ref $x ? $x : [ $x ];
3443 $y = ref $y ? $y : [ $y ];
3445 $self->_set_error("getpixel: x is a reference to an empty array");
3449 $self->_set_error("getpixel: y is a reference to an empty array");
3453 # make both the same length, replicating the last element
3455 $x = [ @$x, ($x->[-1]) x (@$y - @$x) ];
3458 $y = [ @$y, ($y->[-1]) x (@$x - @$y) ];
3462 if ($type eq '8bit') {
3463 for my $i (0..$#$x) {
3464 push(@result, i_get_pixel($self->{IMG}, $x->[$i], $y->[$i]));
3467 elsif ($type eq 'float' || $type eq 'double') {
3468 for my $i (0..$#$x) {
3469 push(@result, i_gpixf($self->{IMG}, $x->[$i], $y->[$i]));
3473 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3476 return wantarray ? @result : \@result;
3479 if ($type eq '8bit') {
3480 return i_get_pixel($self->{IMG}, $x, $y);
3482 elsif ($type eq 'float' || $type eq 'double') {
3483 return i_gpixf($self->{IMG}, $x, $y);
3486 $self->_set_error("getpixel: type must be '8bit' or 'float'");
3494 my %opts = ( type => '8bit', x=>0, @_);
3496 $self->_valid_image("getscanline")
3499 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3501 unless (defined $opts{'y'}) {
3502 $self->_set_error("missing y parameter");
3506 if ($opts{type} eq '8bit') {
3507 return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3510 elsif ($opts{type} eq 'float') {
3511 return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3514 elsif ($opts{type} eq 'index') {
3515 unless (i_img_type($self->{IMG})) {
3516 $self->_set_error("type => index only valid on paletted images");
3519 return i_gpal($self->{IMG}, $opts{x}, $opts{x} + $opts{width},
3523 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3530 my %opts = ( x=>0, @_);
3532 $self->_valid_image("setscanline")
3535 unless (defined $opts{'y'}) {
3536 $self->_set_error("missing y parameter");
3541 if (ref $opts{pixels} && @{$opts{pixels}}) {
3542 # try to guess the type
3543 if ($opts{pixels}[0]->isa('Imager::Color')) {
3544 $opts{type} = '8bit';
3546 elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
3547 $opts{type} = 'float';
3550 $self->_set_error("missing type parameter and could not guess from pixels");
3556 $opts{type} = '8bit';
3560 if ($opts{type} eq '8bit') {
3561 if (ref $opts{pixels}) {
3562 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3565 return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3568 elsif ($opts{type} eq 'float') {
3569 if (ref $opts{pixels}) {
3570 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3573 return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3576 elsif ($opts{type} eq 'index') {
3577 if (ref $opts{pixels}) {
3578 return i_ppal($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
3581 return i_ppal_p($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
3585 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3592 my %opts = ( type => '8bit', x=>0, offset => 0, @_);
3594 $self->_valid_image("getsamples")
3597 defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
3599 unless (defined $opts{'y'}) {
3600 $self->_set_error("missing y parameter");
3604 if ($opts{target}) {
3605 my $target = $opts{target};
3606 my $offset = $opts{offset};
3607 if ($opts{type} eq '8bit') {
3608 my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3609 $opts{y}, $opts{channels})
3611 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3612 return scalar(@samples);
3614 elsif ($opts{type} eq 'float') {
3615 my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3616 $opts{y}, $opts{channels});
3617 @{$target}[$offset .. $offset + @samples - 1] = @samples;
3618 return scalar(@samples);
3620 elsif ($opts{type} =~ /^(\d+)bit$/) {
3624 my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3625 $opts{y}, $bits, $target,
3626 $offset, $opts{channels});
3627 unless (defined $count) {
3628 $self->_set_error(Imager->_error_as_msg);
3635 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3640 if ($opts{type} eq '8bit') {
3641 return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3642 $opts{y}, $opts{channels});
3644 elsif ($opts{type} eq 'float') {
3645 return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3646 $opts{y}, $opts{channels});
3648 elsif ($opts{type} =~ /^(\d+)bit$/) {
3652 i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
3653 $opts{y}, $bits, \@data, 0, $opts{channels})
3658 $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
3667 $self->_valid_image("setsamples")
3670 my %opts = ( x => 0, offset => 0 );
3672 # avoid duplicating the data parameter, it may be a large scalar
3674 while ($i < @_ -1) {
3675 if ($_[$i] eq 'data') {
3679 $opts{$_[$i]} = $_[$i+1];
3685 unless(defined $data_index) {
3686 $self->_set_error('setsamples: data parameter missing');
3689 unless (defined $_[$data_index]) {
3690 $self->_set_error('setsamples: data parameter not defined');
3694 my $type = $opts{type};
3695 defined $type or $type = '8bit';
3697 my $width = defined $opts{width} ? $opts{width}
3698 : $self->getwidth() - $opts{x};
3701 if ($type eq '8bit') {
3702 $count = i_psamp($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3703 $_[$data_index], $opts{offset}, $width);
3705 elsif ($type eq 'float') {
3706 $count = i_psampf($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
3707 $_[$data_index], $opts{offset}, $width);
3709 elsif ($type =~ /^([0-9]+)bit$/) {
3712 unless (ref $_[$data_index]) {
3713 $self->_set_error("setsamples: data must be an array ref for type not 8bit or float");
3717 $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
3718 $opts{channels}, $_[$data_index], $opts{offset},
3722 $self->_set_error('setsamples: type parameter invalid');
3726 unless (defined $count) {
3727 $self->_set_error(Imager->_error_as_msg);
3734 # make an identity matrix of the given size
3738 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
3739 for my $c (0 .. ($size-1)) {
3740 $matrix->[$c][$c] = 1;
3745 # general function to convert an image
3747 my ($self, %opts) = @_;
3750 $self->_valid_image("convert")
3753 unless (defined wantarray) {
3754 my @caller = caller;
3755 warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
3759 # the user can either specify a matrix or preset
3760 # the matrix overrides the preset
3761 if (!exists($opts{matrix})) {
3762 unless (exists($opts{preset})) {
3763 $self->{ERRSTR} = "convert() needs a matrix or preset";
3767 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
3768 # convert to greyscale, keeping the alpha channel if any
3769 if ($self->getchannels == 3) {
3770 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
3772 elsif ($self->getchannels == 4) {
3773 # preserve the alpha channel
3774 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
3779 $matrix = _identity($self->getchannels);
3782 elsif ($opts{preset} eq 'noalpha') {
3783 # strip the alpha channel
3784 if ($self->getchannels == 2 or $self->getchannels == 4) {
3785 $matrix = _identity($self->getchannels);
3786 pop(@$matrix); # lose the alpha entry
3789 $matrix = _identity($self->getchannels);
3792 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
3794 $matrix = [ [ 1 ] ];
3796 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
3797 $matrix = [ [ 0, 1 ] ];
3799 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
3800 $matrix = [ [ 0, 0, 1 ] ];
3802 elsif ($opts{preset} eq 'alpha') {
3803 if ($self->getchannels == 2 or $self->getchannels == 4) {
3804 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
3807 # the alpha is just 1 <shrug>
3808 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
3811 elsif ($opts{preset} eq 'rgb') {
3812 if ($self->getchannels == 1) {
3813 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
3815 elsif ($self->getchannels == 2) {
3816 # preserve the alpha channel
3817 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
3820 $matrix = _identity($self->getchannels);
3823 elsif ($opts{preset} eq 'addalpha') {
3824 if ($self->getchannels == 1) {
3825 $matrix = _identity(2);
3827 elsif ($self->getchannels == 3) {
3828 $matrix = _identity(4);
3831 $matrix = _identity($self->getchannels);
3835 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
3841 $matrix = $opts{matrix};
3844 my $new = Imager->new;
3845 $new->{IMG} = i_convert($self->{IMG}, $matrix);
3846 unless ($new->{IMG}) {
3847 # most likely a bad matrix
3848 i_push_error(0, "convert");
3849 $self->{ERRSTR} = _error_as_msg();
3855 # combine channels from multiple input images, a class method
3857 my ($class, %opts) = @_;
3859 my $src = delete $opts{src};
3861 $class->_set_error("src parameter missing");
3866 for my $img (@$src) {
3867 unless (eval { $img->isa("Imager") }) {
3868 $class->_set_error("src must contain image objects");
3871 unless ($img->_valid_image("combine")) {
3872 $Imager::ERRSTR = $img->{ERRSTR} . " (src->[$index])";
3875 push @imgs, $img->{IMG};
3878 if (my $channels = delete $opts{channels}) {
3879 $result = i_combine(\@imgs, $channels);
3882 $result = i_combine(\@imgs);
3885 $class->_set_error($class->_error_as_msg);
3889 my $img = $class->new;
3890 $img->{IMG} = $result;
3896 # general function to map an image through lookup tables
3899 my ($self, %opts) = @_;
3900 my @chlist = qw( red green blue alpha );
3902 $self->_valid_image("map")
3905 if (!exists($opts{'maps'})) {
3906 # make maps from channel maps
3908 for $chnum (0..$#chlist) {
3909 if (exists $opts{$chlist[$chnum]}) {
3910 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
3911 } elsif (exists $opts{'all'}) {
3912 $opts{'maps'}[$chnum] = $opts{'all'};
3916 if ($opts{'maps'} and $self->{IMG}) {
3917 i_map($self->{IMG}, $opts{'maps'} );
3923 my ($self, %opts) = @_;
3925 $self->_valid_image("difference")
3928 defined $opts{mindist} or $opts{mindist} = 0;
3930 defined $opts{other}
3931 or return $self->_set_error("No 'other' parameter supplied");
3932 unless ($opts{other}->_valid_image("difference")) {
3933 $self->_set_error($opts{other}->errstr . " (other image)");
3937 my $result = Imager->new;
3938 $result->{IMG} = i_diff_image($self->{IMG}, $opts{other}{IMG},
3940 or return $self->_set_error($self->_error_as_msg());
3945 sub rgb_difference {
3946 my ($self, %opts) = @_;
3948 $self->_valid_image("rgb_difference")
3951 defined $opts{other}
3952 or return $self->_set_error("No 'other' parameter supplied");
3953 unless ($opts{other}->_valid_image("rgb_difference")) {
3954 $self->_set_error($opts{other}->errstr . " (other image)");
3958 my $result = Imager->new;
3959 $result->{IMG} = i_rgbdiff_image($self->{IMG}, $opts{other}{IMG})
3960 or return $self->_set_error($self->_error_as_msg());
3965 # destructive border - image is shrunk by one pixel all around
3968 my ($self,%opts)=@_;
3969 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
3970 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
3974 # Get the width of an image
3979 $self->_valid_image("getwidth")
3982 return i_img_get_width($self->{IMG});
3985 # Get the height of an image
3990 $self->_valid_image("getheight")
3993 return i_img_get_height($self->{IMG});
3996 # Get number of channels in an image
4001 $self->_valid_image("getchannels")
4004 return i_img_getchannels($self->{IMG});
4007 my @model_names = qw(unknown gray graya rgb rgba);
4010 my ($self, %opts) = @_;
4012 $self->_valid_image("colormodel")
4015 my $model = i_img_color_model($self->{IMG});
4017 return $opts{numeric} ? $model : $model_names[$model];
4023 $self->_valid_image("colorchannels")
4026 return i_img_color_channels($self->{IMG});
4032 $self->_valid_image("alphachannel")
4035 return scalar(i_img_alpha_channel($self->{IMG}));
4043 $self->_valid_image("getmask")
4046 return i_img_getmask($self->{IMG});
4055 $self->_valid_image("setmask")
4058 unless (defined $opts{mask}) {
4059 $self->_set_error("mask parameter required");
4063 i_img_setmask( $self->{IMG} , $opts{mask} );
4068 # Get number of colors in an image
4072 my %opts=('maxcolors'=>2**30,@_);
4074 $self->_valid_image("getcolorcount")
4077 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
4078 return ($rc==-1? undef : $rc);
4081 # Returns a reference to a hash. The keys are colour named (packed) and the
4082 # values are the number of pixels in this colour.
4083 sub getcolorusagehash {
4086 $self->_valid_image("getcolorusagehash")
4089 my %opts = ( maxcolors => 2**30, @_ );
4090 my $max_colors = $opts{maxcolors};
4091 unless (defined $max_colors && $max_colors > 0) {
4092 $self->_set_error('maxcolors must be a positive integer');
4096 my $channels= $self->getchannels;
4097 # We don't want to look at the alpha channel, because some gifs using it
4098 # doesn't define it for every colour (but only for some)
4099 $channels -= 1 if $channels == 2 or $channels == 4;
4101 my $height = $self->getheight;
4102 for my $y (0 .. $height - 1) {
4103 my $colors = $self->getsamples('y' => $y, channels => [ 0 .. $channels - 1 ]);
4104 while (length $colors) {
4105 $color_use{ substr($colors, 0, $channels, '') }++;
4107 keys %color_use > $max_colors
4113 # This will return a ordered array of the colour usage. Kind of the sorted
4114 # version of the values of the hash returned by getcolorusagehash.
4115 # You might want to add safety checks and change the names, etc...
4119 $self->_valid_image("getcolorusage")
4122 my %opts = ( maxcolors => 2**30, @_ );
4123 my $max_colors = $opts{maxcolors};
4124 unless (defined $max_colors && $max_colors > 0) {
4125 $self->_set_error('maxcolors must be a positive integer');
4129 return i_get_anonymous_color_histo($self->{IMG}, $max_colors);
4132 # draw string to an image
4137 $self->_valid_image("string")
4140 my %input=('x'=>0, 'y'=>0, @_);
4141 defined($input{string}) or $input{string} = $input{text};
4143 unless(defined $input{string}) {
4144 $self->{ERRSTR}="missing required parameter 'string'";
4148 unless($input{font}) {
4149 $self->{ERRSTR}="missing required parameter 'font'";
4153 unless ($input{font}->draw(image=>$self, %input)) {
4165 $self->_valid_image("align_string")
4174 my %input=('x'=>0, 'y'=>0, @_);
4175 defined $input{string}
4176 or $input{string} = $input{text};
4178 unless(exists $input{string}) {
4179 $self->_set_error("missing required parameter 'string'");
4183 unless($input{font}) {
4184 $self->_set_error("missing required parameter 'font'");
4189 unless (@result = $input{font}->align(image=>$img, %input)) {
4193 return wantarray ? @result : $result[0];
4196 my @file_limit_names = qw/width height bytes/;
4198 sub set_file_limits {
4205 @values{@file_limit_names} = (0) x @file_limit_names;
4208 @values{@file_limit_names} = i_get_image_file_limits();
4211 for my $key (keys %values) {
4212 defined $opts{$key} and $values{$key} = $opts{$key};
4215 i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
4218 sub get_file_limits {
4219 i_get_image_file_limits();
4222 my @check_args = qw(width height channels sample_size);
4224 sub check_file_limits {
4234 if ($opts{sample_size} && $opts{sample_size} eq 'float') {
4235 $opts{sample_size} = length(pack("d", 0));
4238 for my $name (@check_args) {
4239 unless (defined $opts{$name}) {
4240 $class->_set_error("check_file_limits: $name must be defined");
4243 unless ($opts{$name} == int($opts{$name})) {
4244 $class->_set_error("check_file_limits: $name must be a positive integer");
4249 my $result = i_int_check_image_file_limits(@opts{@check_args});
4251 $class->_set_error($class->_error_as_msg());
4257 # Shortcuts that can be exported
4259 sub newcolor { Imager::Color->new(@_); }
4260 sub newfont { Imager::Font->new(@_); }
4262 require Imager::Color::Float;
4263 return Imager::Color::Float->new(@_);
4266 *NC=*newcolour=*newcolor;
4273 #### Utility routines
4276 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
4280 my ($self, $msg) = @_;
4283 $self->{ERRSTR} = $msg;
4291 # Default guess for the type of an image from extension
4293 my @simple_types = qw(png tga gif raw ico cur xpm mng jng ilbm pcx psd eps webp xwd xpm dng ras);
4297 ( map { $_ => $_ } @simple_types ),
4303 pnm => "pnm", # technically wrong, but historically it works in Imager
4316 sub def_guess_type {
4319 my ($ext) = $name =~ /\.([^.]+)$/
4322 my $type = $ext_types{$ext}
4328 sub add_type_extensions {
4329 my ($class, $type, @exts) = @_;
4331 for my $ext (@exts) {
4332 exists $ext_types{lc $ext} or $ext_types{lc $ext} = lc $type;
4338 return @combine_types;
4341 # get the minimum of a list
4345 for(@_) { if ($_<$mx) { $mx=$_; }}
4349 # get the maximum of a list
4353 for(@_) { if ($_>$mx) { $mx=$_; }}
4357 # string stuff for iptc headers
4361 $str = substr($str,3);
4362 $str =~ s/[\n\r]//g;
4369 # A little hack to parse iptc headers.
4374 my($caption,$photogr,$headln,$credit);
4376 my $str=$self->{IPTCRAW};
4381 @ar=split(/8BIM/,$str);
4386 @sar=split(/\034\002/);
4387 foreach $item (@sar) {
4388 if ($item =~ m/^x/) {
4389 $caption = _clean($item);
4392 if ($item =~ m/^P/) {
4393 $photogr = _clean($item);
4396 if ($item =~ m/^i/) {
4397 $headln = _clean($item);
4400 if ($item =~ m/^n/) {
4401 $credit = _clean($item);
4407 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
4411 # Inline added a new argument at the beginning
4415 or die "Only C language supported";
4417 require Imager::ExtUtils;
4418 return Imager::ExtUtils->inline_config;
4421 # threads shouldn't try to close raw Imager objects
4422 sub Imager::ImgRaw::CLONE_SKIP { 1 }
4425 # this serves two purposes:
4426 # - a class method to load the file support modules included with Imager
4427 # (or were included, once the library dependent modules are split out)
4428 # - something for Module::ScanDeps to analyze
4429 # https://rt.cpan.org/Ticket/Display.html?id=6566
4432 pop @INC if $INC[-1] eq '.';
4433 eval { require Imager::File::GIF };
4434 eval { require Imager::File::JPEG };
4435 eval { require Imager::File::PNG };
4436 eval { require Imager::File::SGI };
4437 eval { require Imager::File::TIFF };
4438 eval { require Imager::File::ICO };
4439 eval { require Imager::Font::W32 };
4440 eval { require Imager::Font::FT2 };
4441 eval { require Imager::Font::T1 };
4442 eval { require Imager::Color::Table };
4451 my ($class, $fh) = @_;
4454 return $class->new_cb
4459 return print $fh $_[0];
4463 my $count = CORE::read $fh, $tmp, $_[1];
4471 if ($_[1] != SEEK_CUR || $_[0] != 0) {
4472 unless (CORE::seek $fh, $_[0], $_[1]) {
4483 return $class->_new_perlio($fh);
4487 # backward compatibility for %formats
4488 package Imager::FORMATS;
4490 use constant IX_FORMATS => 0;
4491 use constant IX_LIST => 1;
4492 use constant IX_INDEX => 2;
4493 use constant IX_CLASSES => 3;
4496 my ($class, $formats, $classes) = @_;
4498 return bless [ $formats, [ ], 0, $classes ], $class;
4502 my ($self, $key) = @_;
4504 (my $file = $self->[IX_CLASSES]{$key} . ".pm") =~ s(::)(/)g;
4507 my $loaded = Imager::_load_file($file, \$error);
4512 if ($error =~ /^Can't locate /) {
4513 $error = "Can't locate $file";
4515 $reader_load_errors{$key} = $writer_load_errors{$key} = $error;
4518 $self->[IX_FORMATS]{$key} = $value;
4524 my ($self, $key) = @_;
4526 exists $self->[IX_FORMATS]{$key} and return $self->[IX_FORMATS]{$key};
4528 $self->[IX_CLASSES]{$key} or return undef;
4530 return $self->_check($key);
4534 die "%Imager::formats is not user monifiable";
4538 die "%Imager::formats is not user monifiable";
4542 die "%Imager::formats is not user monifiable";
4546 my ($self, $key) = @_;
4548 if (exists $self->[IX_FORMATS]{$key}) {
4549 my $value = $self->[IX_FORMATS]{$key}
4554 $self->_check($key) or return 1==0;
4562 unless (@{$self->[IX_LIST]}) {
4564 @{$self->[IX_LIST]} = grep $self->[IX_FORMATS]{$_},
4565 keys %{$self->[IX_FORMATS]};
4567 for my $key (keys %{$self->[IX_CLASSES]}) {
4568 $self->[IX_FORMATS]{$key} and next;
4570 and push @{$self->[IX_LIST]}, $key;
4574 @{$self->[IX_LIST]} or return;
4575 $self->[IX_INDEX] = 1;
4576 return $self->[IX_LIST][0];
4582 $self->[IX_INDEX] < @{$self->[IX_LIST]}
4585 return $self->[IX_LIST][$self->[IX_INDEX]++];
4591 return scalar @{$self->[IX_LIST]};
4596 # Below is the stub of documentation for your module. You better edit it!
4600 Imager - Perl extension for Generating 24 bit Images
4610 die "Usage: thumbmake.pl filename\n" if !-f $ARGV[0];
4615 # see Imager::Files for information on the read() method
4616 my $img = Imager->new(file=>$file)
4617 or die Imager->errstr();
4619 $file =~ s/\.[^.]*$//;
4621 # Create smaller version
4622 # documented in Imager::Transformations
4623 my $thumb = $img->scale(scalefactor=>.3);
4625 # Autostretch individual channels
4626 $thumb->filter(type=>'autolevels');
4628 # try to save in one of these formats
4631 for $format ( qw( png gif jpeg tiff ppm ) ) {
4632 # Check if given format is supported
4633 if ($Imager::formats{$format}) {
4634 $file.="_low.$format";
4635 print "Storing image as: $file\n";
4636 # documented in Imager::Files
4637 $thumb->write(file=>$file) or
4645 Imager is a module for creating and altering images. It can read and
4646 write various image formats, draw primitive shapes like lines,and
4647 polygons, blend multiple images together in various ways, scale, crop,
4648 render text and more.
4650 =head2 Overview of documentation
4656 Imager - This document - Synopsis, Example, Table of Contents and
4661 L<Imager::Install> - installation notes for Imager.
4665 L<Imager::Tutorial> - a brief introduction to Imager.
4669 L<Imager::Cookbook> - how to do various things with Imager.
4673 L<Imager::ImageTypes> - Basics of constructing image objects with
4674 C<new()>: Direct type/virtual images, RGB(A)/paletted images,
4675 8/16/double bits/channel, color maps, channel masks, image tags, color
4676 quantization. Also discusses basic image information methods.
4680 L<Imager::Files> - IO interaction, reading/writing images, format
4685 L<Imager::Draw> - Drawing Primitives, lines, boxes, circles, arcs,
4690 L<Imager::Color> - Color specification.
4694 L<Imager::Fill> - Fill pattern specification.
4698 L<Imager::Font> - General font rendering, bounding boxes and font
4703 L<Imager::Transformations> - Copying, scaling, cropping, flipping,
4704 blending, pasting, convert and map.
4708 L<Imager::Engines> - Programmable transformations through
4709 C<transform()>, C<transform2()> and C<matrix_transform()>.
4713 L<Imager::Filters> - Filters, sharpen, blur, noise, convolve etc. and
4718 L<Imager::Expr> - Expressions for evaluation engine used by
4723 L<Imager::Matrix2d> - Helper class for affine transformations.
4727 L<Imager::Fountain> - Helper for making gradient profiles.
4731 L<Imager::IO> - Imager I/O abstraction.
4735 L<Imager::API> - using Imager's C API
4739 L<Imager::APIRef> - API function reference
4743 L<Imager::Inline> - using Imager's C API from Inline::C
4747 L<Imager::ExtUtils> - tools to get access to Imager's C API.
4751 L<Imager::Security> - brief security notes.
4755 L<Imager::Threads> - brief information on working with threads.
4759 =head2 Basic Overview
4761 An Image object is created with C<$img = Imager-E<gt>new()>.
4764 $img=Imager->new(); # create empty image
4765 $img->read(file=>'lena.png',type=>'png') or # read image from file
4766 die $img->errstr(); # give an explanation
4767 # if something failed
4769 or if you want to create an empty image:
4771 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
4773 This example creates a completely black image of width 400 and height
4776 =head1 ERROR HANDLING
4778 In general a method will return false when it fails, if it does use
4779 the C<errstr()> method to find out why:
4785 Returns the last error message in that context.
4787 If the last error you received was from calling an object method, such
4788 as read, call errstr() as an object method to find out why:
4790 my $image = Imager->new;
4791 $image->read(file => 'somefile.gif')
4792 or die $image->errstr;
4794 If it was a class method then call errstr() as a class method:
4796 my @imgs = Imager->read_multi(file => 'somefile.gif')
4797 or die Imager->errstr;
4799 Note that in some cases object methods are implemented in terms of
4800 class methods so a failing object method may set both.
4804 The C<Imager-E<gt>new> method is described in detail in
4805 L<Imager::ImageTypes>.
4809 Where to find information on methods for Imager class objects.
4811 addcolors() - L<Imager::ImageTypes/addcolors()> - add colors to a
4814 add_file_magic() - L<Imager::Files/add_file_magic()> - add magic to
4815 Imager's file type detector.
4817 addtag() - L<Imager::ImageTypes/addtag()> - add image tags
4819 add_type_extensions() - L<Imager::Files/add_file_magic()> - add magic
4820 for new image file types.
4822 L<Imager::Files/add_type_extensions($type, $ext, ...)> - add extensions for
4823 new image file types.
4825 align_string() - L<Imager::Draw/align_string()> - draw text aligned on a
4828 alphachannel() - L<Imager::ImageTypes/alphachannel()> - return the
4829 channel index of the alpha channel (if any).
4831 arc() - L<Imager::Draw/arc()> - draw a filled arc
4833 bits() - L<Imager::ImageTypes/bits()> - number of bits per sample for the
4836 box() - L<Imager::Draw/box()> - draw a filled or outline box.
4838 check_file_limits() - L<Imager::Files/check_file_limits()>
4840 circle() - L<Imager::Draw/circle()> - draw a filled circle
4842 close_log() - L<Imager::ImageTypes/close_log()> - close the Imager
4845 colorchannels() - L<Imager::ImageTypes/colorchannels()> - the number
4846 of channels used for color.
4848 colorcount() - L<Imager::ImageTypes/colorcount()> - the number of
4849 colors in an image's palette (paletted images only)
4851 colormodel() - L<Imager::ImageTypes/colorcount()> - how color is
4854 combine() - L<Imager::Transformations/combine()> - combine channels
4855 from one or more images.
4857 combines() - L<Imager::Draw/combines()> - return a list of the
4858 different combine type keywords
4860 compose() - L<Imager::Transformations/compose()> - compose one image
4863 convert() - L<Imager::Transformations/convert()> - transform the color
4866 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
4869 crop() - L<Imager::Transformations/crop()> - extract part of an image
4871 def_guess_type() - L<Imager::Files/def_guess_type()> - default function
4872 used to guess the output file format based on the output file name
4874 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
4876 difference() - L<Imager::Filters/difference()> - produce a difference
4877 images from two input images.
4879 errstr() - L</errstr()> - the error from the last failed operation.
4881 filter() - L<Imager::Filters/filter()> - image filtering
4883 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
4884 palette, if it has one
4886 flip() - L<Imager::Transformations/flip()> - flip an image, vertically,
4889 flood_fill() - L<Imager::Draw/flood_fill()> - fill an enclosed or same
4892 getchannels() - L<Imager::ImageTypes/getchannels()> - the number of
4893 samples per pixel for an image
4895 getcolorcount() - L<Imager::ImageTypes/getcolorcount()> - the number of
4896 different colors used by an image (works for direct color images)
4898 getcolors() - L<Imager::ImageTypes/getcolors()> - get colors from the image
4899 palette, if it has one
4901 getcolorusage() - L<Imager::ImageTypes/getcolorusage()>
4903 getcolorusagehash() - L<Imager::ImageTypes/getcolorusagehash()>
4905 get_file_limits() - L<Imager::Files/get_file_limits()>
4907 getheight() - L<Imager::ImageTypes/getheight()> - height of the image in
4910 getmask() - L<Imager::ImageTypes/getmask()> - write mask for the image
4912 getpixel() - L<Imager::Draw/getpixel()> - retrieve one or more pixel
4915 getsamples() - L<Imager::Draw/getsamples()> - retrieve samples from a
4916 row or partial row of pixels.
4918 getscanline() - L<Imager::Draw/getscanline()> - retrieve colors for a
4919 row or partial row of pixels.
4921 getwidth() - L<Imager::ImageTypes/getwidth()> - width of the image in
4924 img_set() - L<Imager::ImageTypes/img_set()> - re-use an Imager object
4927 init() - L<Imager::ImageTypes/init()>
4929 is_bilevel() - L<Imager::ImageTypes/is_bilevel()> - returns whether
4930 image write functions should write the image in their bilevel (blank
4931 and white, no gray levels) format
4933 is_logging() L<Imager::ImageTypes/is_logging()> - test if the debug
4936 line() - L<Imager::Draw/line()> - draw an interval
4938 load_plugin() - L<Imager::Filters/load_plugin()>
4940 log() - L<Imager::ImageTypes/log()> - send a message to the debugging
4943 make_palette() - L<Imager::ImageTypes/make_palette()> - produce a
4944 color palette from one or more input images.
4946 map() - L<Imager::Transformations/map()> - remap color
4949 masked() - L<Imager::ImageTypes/masked()> - make a masked image
4951 matrix_transform() - L<Imager::Engines/matrix_transform()>
4953 maxcolors() - L<Imager::ImageTypes/maxcolors()>
4955 NC() - L<Imager::Handy/NC()>
4957 NCF() - L<Imager::Handy/NCF()>
4959 new() - L<Imager::ImageTypes/new()>
4961 newcolor() - L<Imager::Handy/newcolor()>
4963 newcolour() - L<Imager::Handy/newcolour()>
4965 newfont() - L<Imager::Handy/newfont()>
4967 NF() - L<Imager::Handy/NF()>
4969 open() - L<Imager::Files/read()> - an alias for read()
4971 open_log() - L<Imager::ImageTypes/open_log()> - open the debug log.
4975 parseiptc() - L<Imager::Files/parseiptc()> - parse IPTC data from a JPEG
4978 paste() - L<Imager::Transformations/paste()> - draw an image onto an
4981 polygon() - L<Imager::Draw/polygon()>
4983 polyline() - L<Imager::Draw/polyline()>
4985 polypolygon() - L<Imager::Draw/polypolygon()>
4987 preload() - L<Imager::Files/preload()>
4989 read() - L<Imager::Files/read()> - read a single image from an image file
4991 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
4994 read_types() - L<Imager::Files/read_types()> - list image types Imager
4997 register_filter() - L<Imager::Filters/register_filter()>
4999 register_reader() - L<Imager::Files/register_reader()>
5001 register_writer() - L<Imager::Files/register_writer()>
5003 rgb_difference() - L<Imager::Filters/rgb_difference()> - produce a difference
5004 images from two input images.
5006 rotate() - L<Imager::Transformations/rotate()>
5008 rubthrough() - L<Imager::Transformations/rubthrough()> - draw an image
5009 onto an image and use the alpha channel
5011 scale() - L<Imager::Transformations/scale()>
5013 scale_calculate() - L<Imager::Transformations/scale_calculate()>
5015 scaleX() - L<Imager::Transformations/scaleX()>
5017 scaleY() - L<Imager::Transformations/scaleY()>
5019 setcolors() - L<Imager::ImageTypes/setcolors()> - set palette colors
5022 set_file_limits() - L<Imager::Files/set_file_limits()>
5024 setmask() - L<Imager::ImageTypes/setmask()>
5026 setpixel() - L<Imager::Draw/setpixel()>
5028 setsamples() - L<Imager::Draw/setsamples()>
5030 setscanline() - L<Imager::Draw/setscanline()>
5032 settag() - L<Imager::ImageTypes/settag()>
5034 string() - L<Imager::Draw/string()> - draw text on an image
5036 tags() - L<Imager::ImageTypes/tags()> - fetch image tags
5038 to_paletted() - L<Imager::ImageTypes/to_paletted()>
5040 to_rgb16() - L<Imager::ImageTypes/to_rgb16()>
5042 to_rgb8() - L<Imager::ImageTypes/to_rgb8()>
5044 to_rgb_double() - L<Imager::ImageTypes/to_rgb_double()> - convert to
5045 double per sample image.
5047 transform() - L<Imager::Engines/"transform()">
5049 transform2() - L<Imager::Engines/"transform2()">
5051 type() - L<Imager::ImageTypes/type()> - type of image (direct vs paletted)
5053 unload_plugin() - L<Imager::Filters/unload_plugin()>
5055 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
5058 write() - L<Imager::Files/write()> - write an image to a file
5060 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
5063 write_types() - L<Imager::Files/read_types()> - list image types Imager
5066 =head1 CONCEPT INDEX
5068 animated GIF - L<Imager::Files/"Writing an animated GIF">
5070 aspect ratio - C<i_xres>, C<i_yres>, C<i_aspect_only> in
5071 L<Imager::ImageTypes/"Common Tags">.
5073 blend - alpha blending one image onto another
5074 L<Imager::Transformations/rubthrough()>
5076 blur - L<< Imager::Filters/C<gaussian> >>, L<< Imager::Filters/C<conv> >>
5078 boxes, drawing - L<Imager::Draw/box()>
5080 changes between image - L<Imager::Filters/"Image Difference">
5082 channels, combine into one image - L<Imager::Transformations/combine()>
5084 color - L<Imager::Color>
5086 color names - L<Imager::Color>, L<Imager::Color::Table>
5088 combine modes - L<Imager::Draw/"Combine Types">
5090 compare images - L<Imager::Filters/"Image Difference">
5092 contrast - L<< Imager::Filters/C<contrast> >>, L<< Imager::Filters/C<autolevels> >>
5094 convolution - L<< Imager::Filters/C<conv> >>
5096 cropping - L<Imager::Transformations/crop()>
5098 CUR files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
5100 C<diff> images - L<Imager::Filters/"Image Difference">
5102 dpi - C<i_xres>, C<i_yres> in L<Imager::ImageTypes/"Common Tags">,
5103 L<Imager::Cookbook/"Image spatial resolution">
5105 drawing boxes - L<Imager::Draw/box()>
5107 drawing lines - L<Imager::Draw/line()>
5109 drawing text - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>
5111 error message - L</"ERROR HANDLING">
5113 files, font - L<Imager::Font>
5115 files, image - L<Imager::Files>
5117 filling, types of fill - L<Imager::Fill>
5119 filling, boxes - L<Imager::Draw/box()>
5121 filling, flood fill - L<Imager::Draw/flood_fill()>
5123 flood fill - L<Imager::Draw/flood_fill()>
5125 fonts - L<Imager::Font>
5127 fonts, drawing with - L<Imager::Draw/string()>,
5128 L<Imager::Draw/align_string()>, L<Imager::Font::Wrap>
5130 fonts, metrics - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
5132 fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
5134 fountain fill - L<Imager::Fill/"Fountain fills">,
5135 L<< Imager::Filters/C<fountain> >>, L<Imager::Fountain>,
5136 L<< Imager::Filters/C<gradgen> >>
5138 GIF files - L<Imager::Files/"GIF">
5140 GIF files, animated - L<Imager::Files/"Writing an animated GIF">
5142 gradient fill - L<Imager::Fill/"Fountain fills">,
5143 L<< Imager::Filters/C<fountain> >>, L<Imager::Fountain>,
5144 L<< Imager::Filters/C<gradgen> >>
5146 gray scale, convert image to - L<Imager::Transformations/convert()>
5148 gaussian blur - L<< Imager::Filters/C<gaussian> >>, L<< Imager::Filters/C<gaussian2> >>
5150 hatch fills - L<Imager::Fill/"Hatched fills">
5152 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
5154 invert image - L<< Imager::Filters/C<hardinvert> >>,
5155 L<< Imager::Filters/C<hardinvertall> >>
5157 JPEG - L<Imager::Files/"JPEG">
5159 limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
5161 lines, drawing - L<Imager::Draw/line()>
5163 matrix - L<Imager::Matrix2d>,
5164 L<Imager::Engines/"Matrix Transformations">,
5165 L<Imager::Font/transform()>
5167 metadata, image - L<Imager::ImageTypes/"Tags">, L<Image::ExifTool>
5169 mosaic - L<< Imager::Filters/C<mosaic> >>
5171 noise, filter - L<< Imager::Filters/C<noise> >>
5173 noise, rendered - L<< Imager::Filters/C<turbnoise> >>,
5174 L<< Imager::Filters/C<radnoise> >>
5176 paste - L<Imager::Transformations/paste()>,
5177 L<Imager::Transformations/rubthrough()>
5179 pseudo-color image - L<Imager::ImageTypes/to_paletted()>,
5180 L<Imager::ImageTypes/new()>
5182 =for stopwords posterize
5184 posterize - L<< Imager::Filters/C<postlevels> >>
5186 PNG files - L<Imager::Files>, L<Imager::Files/"PNG">
5188 PNM - L<Imager::Files/"PNM (Portable aNy Map)">
5190 rectangles, drawing - L<Imager::Draw/box()>
5192 resizing an image - L<Imager::Transformations/scale()>,
5193 L<Imager::Transformations/crop()>
5195 RGB (SGI) files - L<Imager::Files/"SGI (RGB, BW)">
5197 saving an image - L<Imager::Files>
5199 scaling - L<Imager::Transformations/scale()>
5201 security - L<Imager::Security>
5203 SGI files - L<Imager::Files/"SGI (RGB, BW)">
5205 sharpen - L<< Imager::Filters/C<unsharpmask> >>, L<< Imager::Filters/C<conv> >>
5207 size, image - L<Imager::ImageTypes/getwidth()>,
5208 L<Imager::ImageTypes/getheight()>
5210 size, text - L<Imager::Font/bounding_box()>
5212 tags, image metadata - L<Imager::ImageTypes/"Tags">
5214 text, drawing - L<Imager::Draw/string()>, L<Imager::Draw/align_string()>,
5215 L<Imager::Font::Wrap>
5217 text, wrapping text in an area - L<Imager::Font::Wrap>
5219 text, measuring - L<Imager::Font/bounding_box()>, L<Imager::Font::BBox>
5221 threads - L<Imager::Threads>
5223 tiles, color - L<< Imager::Filters/C<mosaic> >>
5225 transparent images - L<Imager::ImageTypes>,
5226 L<Imager::Cookbook/"Transparent PNG">
5228 =for stopwords unsharp
5230 unsharp mask - L<< Imager::Filters/C<unsharpmask> >>
5232 watermark - L<< Imager::Filters/C<watermark> >>
5234 writing an image to a file - L<Imager::Files>
5238 The best place to get help with Imager is the mailing list.
5240 To subscribe send a message with C<subscribe> in the body to:
5242 imager-devel+request@molar.is
5248 L<http://www.molar.is/en/lists/imager-devel/>
5252 where you can also find the mailing list archive.
5254 You can report bugs either via github at:
5258 L<https://github.com/tonycoz/imager/issues>
5266 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
5270 or by sending an email to:
5274 bug-Imager@rt.cpan.org
5278 Please remember to include the versions of Imager, perl, supporting
5279 libraries, and any relevant code. If you have specific images that
5280 cause the problems, please include those too.
5282 =head1 CONTRIBUTING TO IMAGER
5288 You can send email to the maintainer below.
5290 If you send me a bug report via email, it will be copied to Request
5295 I accept patches, preferably against the master branch in git. Please
5296 include an explanation of the reason for why the patch is needed or
5299 Your patch should include regression tests where possible, otherwise
5300 it will be delayed until I get a chance to write them.
5302 To browse Imager's git repository:
5304 https://github.com/tonycoz/imager.git
5308 git clone git://github.com/tonycoz/imager.git
5310 Or you can create a fork as usual on github and submit a github pull
5313 Patches can either be submitted as a github pull request or by using
5314 C<git format-patch>, for example, if you made your changes in a branch
5315 from master you might do:
5317 git format-patch -k --stdout master >my-patch.txt
5319 and then attach that to your bug report, either by adding it as an
5320 attachment in your email client, or by using the Request Tracker
5321 attachment mechanism.
5325 Tony Cook <tonyc@cpan.org> is the current maintainer for Imager.
5327 Arnar M. Hrafnkelsson is the original author of Imager.
5329 Many others have contributed to Imager, please see the C<README> for a
5334 Imager is licensed under the same terms as perl itself.
5337 makeblendedfont Fontforge
5339 A test font, generated by the Debian packaged Fontforge,
5340 F<FT2/fontfiles/MMOne.pfb>, contains a Postscript operator definition
5341 copyrighted by Adobe. See F<adobe.txt> in the source for license
5346 L<perl>(1), L<Imager::ImageTypes>(3), L<Imager::Files>(3),
5347 L<Imager::Draw>(3), L<Imager::Color>(3), L<Imager::Fill>(3),
5348 L<Imager::Font>(3), L<Imager::Transformations>(3),
5349 L<Imager::Engines>(3), L<Imager::Filters>(3), L<Imager::Expr>(3),
5350 L<Imager::Matrix2d>(3), L<Imager::Fountain>(3)
5352 L<http://imager.perl.org/>
5354 L<Affix::Infix2Postfix>(3), L<Parse::RecDescent>(3)
5356 Other perl imaging modules include:
5358 L<GD>(3), L<Image::Magick>(3),
5359 L<Graphics::Magick|http://www.graphicsmagick.org/perl.html>(3),
5360 L<Prima::Image>, L<IPA>.
5362 For manipulating image metadata see L<Image::ExifTool>.
5364 If you're trying to use Imager for array processing, you should
5365 probably using L<PDL>.