require Exporter;
require DynaLoader;
- $VERSION = '0.43';
+ $VERSION = '0.45';
@ISA = qw(Exporter DynaLoader);
bootstrap Imager $VERSION;
}
callsub => sub { my %hsh=@_; i_conv($hsh{image},$hsh{coef}); }
};
- $filters{gradgen} ={
- callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
- defaults => { },
- callsub => sub { my %hsh=@_; i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
- };
+ $filters{gradgen} =
+ {
+ callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
+ defaults => { dist => 0 },
+ callsub =>
+ sub {
+ my %hsh=@_;
+ my @colors = @{$hsh{colors}};
+ $_ = _color($_)
+ for @colors;
+ i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, $hsh{dist});
+ }
+ };
$filters{nearest_color} ={
callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
callsub =>
sub {
my %hsh = @_;
+
+ # make sure the segments are specified with colors
+ my @segments;
+ for my $segment (@{$hsh{segments}}) {
+ my @new_segment = @$segment;
+
+ $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
+ push @segments, \@new_segment;
+ }
+
i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
$hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
- $hsh{ssample_param}, $hsh{segments});
+ $hsh{ssample_param}, \@segments);
},
};
$filters{unsharpmask} =
$self->{ERRSTR}=undef; #
$self->{DEBUG}=$DEBUG;
$self->{DEBUG} && print "Initialized Imager\n";
- if ($hsh{xsize} && $hsh{ysize}) { $self->img_set(%hsh); }
+ if (defined $hsh{xsize} && defined $hsh{ysize}) {
+ unless ($self->img_set(%hsh)) {
+ $Imager::ERRSTR = $self->{ERRSTR};
+ return;
+ }
+ }
return $self;
}
my $self = shift;
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
my $newcopy=Imager->new();
$newcopy->{IMG}=i_img_new();
i_copy($newcopy->{IMG},$self->{IMG});
sub crop {
my $self=shift;
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
- my %hsh=(left=>0,right=>$self->getwidth(),top=>0,bottom=>$self->getheight(),@_);
+
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
+ return;
+ }
- my ($w,$h,$l,$r,$b,$t)=($self->getwidth(),$self->getheight(),
- @hsh{qw(left right bottom top)});
- $l=0 if not defined $l;
- $t=0 if not defined $t;
+ my %hsh=@_;
- $r||=$l+delete $hsh{'width'} if defined $l and exists $hsh{'width'};
- $b||=$t+delete $hsh{'height'} if defined $t and exists $hsh{'height'};
- $l||=$r-delete $hsh{'width'} if defined $r and exists $hsh{'width'};
- $t||=$b-delete $hsh{'height'} if defined $b and exists $hsh{'height'};
+ my ($w, $h, $l, $r, $b, $t) =
+ @hsh{qw(width height left right bottom top)};
- $r=$self->getwidth if not defined $r;
- $b=$self->getheight if not defined $b;
+ # work through the various possibilities
+ if (defined $l) {
+ if (defined $w) {
+ $r = $l + $w;
+ }
+ elsif (!defined $r) {
+ $r = $self->getwidth;
+ }
+ }
+ elsif (defined $r) {
+ if (defined $w) {
+ $l = $r - $w;
+ }
+ else {
+ $l = 0;
+ }
+ }
+ elsif (defined $w) {
+ $l = int(0.5+($self->getwidth()-$w)/2);
+ $r = $l + $w;
+ }
+ else {
+ $l = 0;
+ $r = $self->getwidth;
+ }
+ if (defined $t) {
+ if (defined $h) {
+ $b = $t + $h;
+ }
+ elsif (!defined $b) {
+ $b = $self->getheight;
+ }
+ }
+ elsif (defined $b) {
+ if (defined $h) {
+ $t = $b - $h;
+ }
+ else {
+ $t = 0;
+ }
+ }
+ elsif (defined $h) {
+ $t=int(0.5+($self->getheight()-$h)/2);
+ $b=$t+$h;
+ }
+ else {
+ $t = 0;
+ $b = $self->getheight;
+ }
($l,$r)=($r,$l) if $l>$r;
($t,$b)=($b,$t) if $t>$b;
- if ($hsh{'width'}) {
- $l=int(0.5+($w-$hsh{'width'})/2);
- $r=$l+$hsh{'width'};
- } else {
- $hsh{'width'}=$r-$l;
- }
- if ($hsh{'height'}) {
- $b=int(0.5+($h-$hsh{'height'})/2);
- $t=$h+$hsh{'height'};
- } else {
- $hsh{'height'}=$b-$t;
- }
+ $l < 0 and $l = 0;
+ $r > $self->getwidth and $r = $self->getwidth;
+ $t < 0 and $t = 0;
+ $b > $self->getheight and $b = $self->getheight;
-# print "l=$l, r=$r, h=$hsh{'width'}\n";
-# print "t=$t, b=$b, w=$hsh{'height'}\n";
+ if ($l == $r || $t == $b) {
+ $self->_set_error("resulting image would have no content");
+ return;
+ }
- my $dst=Imager->new(xsize=>$hsh{'width'}, ysize=>$hsh{'height'}, channels=>$self->getchannels());
+ my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
return $dst;
}
+sub _sametype {
+ my ($self, %opts) = @_;
+
+ $self->{IMG} or return $self->_set_error("Not a valid image");
+
+ my $x = $opts{xsize} || $self->getwidth;
+ my $y = $opts{ysize} || $self->getheight;
+ my $channels = $opts{channels} || $self->getchannels;
+
+ my $out = Imager->new;
+ if ($channels == $self->getchannels) {
+ $out->{IMG} = i_sametype($self->{IMG}, $x, $y);
+ }
+ else {
+ $out->{IMG} = i_sametype_chans($self->{IMG}, $x, $y, $channels);
+ }
+ unless ($out->{IMG}) {
+ $self->{ERRSTR} = $self->_error_as_msg;
+ return;
+ }
+
+ return $out;
+}
+
# Sets an image to a certain size and channel number
# if there was previously data in the image it is discarded
$self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
$hsh{'channels'});
}
+
+ unless ($self->{IMG}) {
+ $self->{ERRSTR} = Imager->_error_as_msg();
+ return;
+ }
+
+ $self;
}
# created a masked version of the current image
$opts = shift;
}
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
my $result = Imager->new;
$result->{IMG} = i_img_to_pal($self->{IMG}, $opts);
#print "Type ", i_img_type($result->{IMG}), "\n";
- $result->{IMG} or undef $result;
-
- return $result;
+ if ($result->{IMG}) {
+ return $result;
+ }
+ else {
+ $self->{ERRSTR} = $self->_error_as_msg;
+ return;
+ }
}
# convert a paletted (or any image) to an 8-bit/channel RGB images
my $self = shift;
my $result;
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "to_rgb8() called in void context - to_rgb8() returns the cropped image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
if ($self->{IMG}) {
$result = Imager->new;
$result->{IMG} = i_img_to_rgb($self->{IMG})
undef($self->{IMG});
}
- # FIXME: Find the format here if not specified
- # yes the code isn't here yet - next week maybe?
- # Next week? Are you high or something? That comment
- # has been there for half a year dude.
- # Look, i just work here, ok?
-
my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
unless ($input{'type'}) {
- $input{'type'} = i_test_format_probe($IO, -1);
- }
+ $input{'type'} = i_test_format_probe($IO, -1);
+ }
unless ($input{'type'}) {
$self->_set_error('type parameter missing and not possible to guess from extension');
return undef;
}
+ unless ($formats{$input{'type'}}) {
+ $self->_set_error("format '$input{'type'}' not supported");
+ return;
+ }
+
# Setup data source
if ( $input{'type'} eq 'jpeg' ) {
($self->{IMG},$self->{IPTCRAW}) = i_readjpeg_wiol( $IO );
if ( !defined($self->{IMG}) ) {
- $self->{ERRSTR}='unable to read jpeg image'; return undef;
+ $self->{ERRSTR}=$self->_error_as_msg(); return undef;
}
$self->{DEBUG} && print "loading a jpeg file\n";
return $self;
}
if ( $input{'type'} eq 'tiff' ) {
- $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
+ my $page = $input{'page'};
+ defined $page or $page = 0;
+ # Fixme, check if that length parameter is ever needed
+ $self->{IMG}=i_readtiff_wiol( $IO, -1, $page );
if ( !defined($self->{IMG}) ) {
$self->{ERRSTR}=$self->_error_as_msg(); return undef;
}
if ( $input{'type'} eq 'png' ) {
$self->{IMG}=i_readpng_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
if ( !defined($self->{IMG}) ) {
- $self->{ERRSTR}='unable to read png image';
+ $self->{ERRSTR} = $self->_error_as_msg();
return undef;
}
$self->{DEBUG} && print "loading a png file\n";
$self->{ERRSTR} = "option 'colors' must be a scalar reference";
return undef;
}
- if ($input{colors}) {
- my $colors;
- ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
- if ($colors) {
- ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
+ if ($input{'gif_consolidate'}) {
+ if ($input{colors}) {
+ my $colors;
+ ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
+ if ($colors) {
+ ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
+ }
+ }
+ else {
+ $self->{IMG} =i_readgif_wiol( $IO );
}
}
else {
- $self->{IMG} =i_readgif_wiol( $IO );
+ my $page = $input{'page'};
+ defined $page or $page = 0;
+ $self->{IMG} = i_readgif_single_wiol( $IO, $page );
+ if ($input{colors}) {
+ ${ $input{colors} } =
+ [ i_getcolors($self->{IMG}, 0, i_colorcount($self->{IMG})) ];
+ }
}
+
if ( !defined($self->{IMG}) ) {
$self->{ERRSTR}=$self->_error_as_msg();
return undef;
$input{make_colors} = 'webmap'; # ignored
$input{translate} = 'giflib';
}
- $rc = i_writegif_wiol($IO, \%input, $self->{IMG});
+ if (!i_writegif_wiol($IO, \%input, $self->{IMG})) {
+ $self->{ERRSTR} = $self->_error_as_msg;
+ return;
+ }
}
if (exists $input{'data'}) {
}
}
- &{$filters{$input{'type'}}{callsub}}(%hsh);
+ eval {
+ local $SIG{__DIE__}; # we don't want this processed by confess, etc
+ &{$filters{$input{'type'}}{callsub}}(%hsh);
+ };
+ if ($@) {
+ chomp($self->{ERRSTR} = $@);
+ return;
+ }
my @b=keys %hsh;
my $img = Imager->new();
my $tmp = Imager->new();
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "scale() called in void context - scale() returns the scaled image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
my $self=shift;
my %opts=(scalefactor=>0.5,@_);
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
my $img = Imager->new();
my $self=shift;
my %opts=(scalefactor=>0.5,@_);
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
my $img = Imager->new();
sub rotate {
my $self = shift;
my %opts = @_;
+
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
if (defined $opts{right}) {
my $degrees = $opts{right};
if ($degrees < 0) {
my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
my $result = Imager->new;
- if ($result->{IMG} = i_rotate_exact($self->{IMG}, $amount)) {
+ if ($opts{back}) {
+ $result->{IMG} = i_rotate_exact($self->{IMG}, $amount, $opts{back});
+ }
+ else {
+ $result->{IMG} = i_rotate_exact($self->{IMG}, $amount);
+ }
+ if ($result->{IMG}) {
return $result;
}
else {
}
}
else {
- $self->{ERRSTR} = "Only the 'right' parameter is available";
+ $self->{ERRSTR} = "Only the 'right', 'radians' and 'degrees' parameters are available";
return undef;
}
}
my $self = shift;
my %opts = @_;
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
if ($opts{matrix}) {
my $xsize = $opts{xsize} || $self->getwidth;
my $ysize = $opts{ysize} || $self->getheight;
my $result = Imager->new;
- $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
- $opts{matrix})
- or return undef;
+ if ($opts{back}) {
+ $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
+ $opts{matrix}, $opts{back})
+ or return undef;
+ }
+ else {
+ $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
+ $opts{matrix})
+ or return undef;
+ }
return $result;
}
$self;
}
+sub getscanline {
+ my $self = shift;
+ my %opts = ( type => '8bit', x=>0, @_);
+
+ defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
+
+ unless (defined $opts{'y'}) {
+ $self->_set_error("missing y parameter");
+ return;
+ }
+
+ if ($opts{type} eq '8bit') {
+ return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+ $opts{y});
+ }
+ elsif ($opts{type} eq 'float') {
+ return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+ $opts{y});
+ }
+ else {
+ $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+ return;
+ }
+}
+
+sub setscanline {
+ my $self = shift;
+ my %opts = ( x=>0, @_);
+
+ unless (defined $opts{'y'}) {
+ $self->_set_error("missing y parameter");
+ return;
+ }
+
+ if (!$opts{type}) {
+ if (ref $opts{pixels} && @{$opts{pixels}}) {
+ # try to guess the type
+ if ($opts{pixels}[0]->isa('Imager::Color')) {
+ $opts{type} = '8bit';
+ }
+ elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
+ $opts{type} = 'float';
+ }
+ else {
+ $self->_set_error("missing type parameter and could not guess from pixels");
+ return;
+ }
+ }
+ else {
+ # default
+ $opts{type} = '8bit';
+ }
+ }
+
+ if ($opts{type} eq '8bit') {
+ if (ref $opts{pixels}) {
+ return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
+ }
+ else {
+ return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
+ }
+ }
+ elsif ($opts{type} eq 'float') {
+ if (ref $opts{pixels}) {
+ return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
+ }
+ else {
+ return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
+ }
+ }
+ else {
+ $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+ return;
+ }
+}
+
+sub getsamples {
+ my $self = shift;
+ my %opts = ( type => '8bit', x=>0, @_);
+
+ defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
+
+ unless (defined $opts{'y'}) {
+ $self->_set_error("missing y parameter");
+ return;
+ }
+
+ unless ($opts{channels}) {
+ $opts{channels} = [ 0 .. $self->getchannels()-1 ];
+ }
+
+ if ($opts{type} eq '8bit') {
+ return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+ $opts{y}, @{$opts{channels}});
+ }
+ elsif ($opts{type} eq 'float') {
+ return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+ $opts{y}, @{$opts{channels}});
+ }
+ else {
+ $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+ return;
+ }
+}
+
# make an identity matrix of the given size
sub _identity {
my ($size) = @_;
my ($self, %opts) = @_;
my $matrix;
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
# the user can either specify a matrix or preset
# the matrix overrides the preset
if (!exists($opts{matrix})) {
return $self;
}
+my @file_limit_names = qw/width height bytes/;
+
+sub set_file_limits {
+ shift;
+
+ my %opts = @_;
+ my %values;
+
+ if ($opts{reset}) {
+ @values{@file_limit_names} = (0) x @file_limit_names;
+ }
+ else {
+ @values{@file_limit_names} = i_get_image_file_limits();
+ }
+
+ for my $key (keys %values) {
+ defined $opts{$key} and $values{$key} = $opts{$key};
+ }
+
+ i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
+}
+
+sub get_file_limits {
+ i_get_image_file_limits();
+}
+
# Shortcuts that can be exported
sub newcolor { Imager::Color->new(@_); }
my $format;
my $img = Imager->new();
- # see Imager::Files for information on the open() method
- $img->open(file=>$file) or die $img->errstr();
+ # see Imager::Files for information on the read() method
+ $img->read(file=>$file) or die $img->errstr();
$file =~ s/\.[^.]*$//;
=item *
+L<Imager::Tutorial> - a brief introduction to Imager.
+
+=item *
+
+L<Imager::Cookbook> - how to do various things with Imager.
+
+=item *
+
L<Imager::ImageTypes> - Basics of constructing image objects with
C<new()>: Direct type/virtual images, RGB(A)/paletted images,
8/16/double bits/channel, color maps, channel masks, image tags, color
Examples:
$img=Imager->new(); # create empty image
- $img->open(file=>'lena.png',type=>'png') or # read image from file
+ $img->read(file=>'lena.png',type=>'png') or # read image from file
die $img->errstr(); # give an explanation
# if something failed
In cases where no image object is associated with an operation
C<$Imager::ERRSTR> is used to report errors not directly associated
-with an image object.
+with an image object. You can also call C<Imager->errstr> to get this
+value.
The C<Imager-E<gt>new> method is described in detail in
L<Imager::ImageTypes>.
+=head1 METHOD INDEX
+
+Where to find information on methods for Imager class objects.
+
+addcolors() - L<Imager::ImageTypes>
+
+addtag() - L<Imager::ImageTypes> - add image tags
+
+arc() - L<Imager::Draw/arc>
+
+bits() - L<Imager::ImageTypes> - number of bits per sample for the
+image
+
+box() - L<Imager::Draw/box>
+
+circle() - L<Imager::Draw/circle>
+
+colorcount() - L<Imager::Draw/colorcount>
+
+convert() - L<Imager::Transformations/"Color transformations"> -
+transform the color space
+
+copy() - L<Imager::Transformations/copy>
+
+crop() - L<Imager::Transformations/crop> - extract part of an image
+
+deltag() - L<Imager::ImageTypes> - delete image tags
+
+difference() - L<Imager::Filters/"Image Difference">
+
+errstr() - L<Imager/"Basic Overview">
+
+filter() - L<Imager::Filters>
+
+findcolor() - L<Imager::ImageTypes> - search the image palette, if it
+has one
+
+flip() - L<Imager::Transformations/flip>
+
+flood_fill() - L<Imager::Draw/flood_fill>
+
+getchannels() - L<Imager::ImageTypes>
+
+getcolorcount() - L<Imager::ImageTypes>
+
+getcolors() - L<Imager::ImageTypes> - get colors from the image
+palette, if it has one
+
+get_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
+
+getheight() - L<Imager::ImageTypes>
+
+getpixel() - L<Imager::Draw/setpixel and getpixel>
+
+getsamples() - L<Imager::Draw/getsamples>
+
+getscanline() - L<Imager::Draw/getscanline>
+
+getwidth() - L<Imager::ImageTypes>
+
+img_set() - L<Imager::ImageTypes>
+
+line() - L<Imager::Draw/line>
+
+map() - L<Imager::Transformations/"Color Mappings"> - remap color
+channel values
+
+masked() - L<Imager::ImageTypes> - make a masked image
+
+matrix_transform() - L<Imager::Engines/"Matrix Transformations">
+
+maxcolors() - L<Imager::ImageTypes/maxcolor>
+
+new() - L<Imager::ImageTypes>
+
+open() - L<Imager::Files> - an alias for read()
+
+paste() - L<Imager::Transformations/paste> - draw an image onto an image
+
+polygon() - L<Imager::Draw/polygon>
+
+polyline() - L<Imager::Draw/polyline>
+
+read() - L<Imager::Files> - read a single image from an image file
+
+read_multi() - L<Imager::Files> - read multiple images from an image
+file
+
+rotate() - L<Imager::Transformations/rotate>
+
+rubthrough() - L<Imager::Transformations/rubthrough> - draw an image onto an
+image and use the alpha channel
+
+scale() - L<Imager::Transformations/scale>
+
+setscanline() - L<Imager::Draw/setscanline>
+
+scaleX() - L<Imager::Transformations/scaleX>
+
+scaleY() - L<Imager::Transformations/scaleY>
+
+setcolors() - L<Imager::ImageTypes> - set palette colors in a paletted image
+
+setpixel() - L<Imager::Draw/setpixel and getpixel>
+
+set_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
+
+string() - L<Imager::Font/string> - draw text on an image
+
+tags() - L<Imager::ImageTypes> - fetch image tags
+
+to_paletted() - L<Imager::ImageTypes>
+
+to_rgb8() - L<Imager::ImageTypes>
+
+transform() - L<Imager::Engines/"transform">
+
+transform2() - L<Imager::Engines/"transform2">
+
+type() - L<Imager::ImageTypes> - type of image (direct vs paletted)
+
+virtual() - L<Imager::ImageTypes> - whether the image has it's own
+data
+
+write() - L<Imager::Files> - write an image to a file
+
+write_multi() - L<Imager::Files> - write multiple image to an image
+file.
+
+=head1 CONCEPT INDEX
+
+animated GIF - L<Imager::File/"Writing an animated GIF">
+
+aspect ratio - L<Imager::ImageTypes/i_xres>,
+L<Imager::ImageTypes/i_yres>, L<Imager::ImageTypes/i_aspect_only>
+
+blur - L<Imager::Filters/guassian>, L<Imager::Filters/conv>
+
+boxes, drawing - L<Imager::Draw/box>
+
+color - L<Imager::Color>
+
+color names - L<Imager::Color>, L<Imager::Color::Table>
+
+combine modes - L<Imager::Fill/combine>
+
+contrast - L<Imager::Filter/contrast>, L<Imager::Filter/autolevels>
+
+convolution - L<Imager::Filter/conv>
+
+cropping - L<Imager::Transformations/crop>
+
+dpi - L<Imager::ImageTypes/i_xres>
+
+drawing boxes - L<Imager::Draw/box>
+
+drawing lines - L<Imager::Draw/line>
+
+drawing text - L<Imager::Font/string>, L<Imager::Font/align>
+
+error message - L<Imager/"Basic Overview">
+
+files, font - L<Imager::Font>
+
+files, image - L<Imager::Files>
+
+filling, types of fill - L<Imager::Fill>
+
+filling, boxes - L<Imager::Draw/box>
+
+filling, flood fill - L<Imager::Draw/flood_fill>
+
+flood fill - L<Imager::Draw/flood_fill>
+
+fonts - L<Imager::Font>
+
+fonts, drawing with - L<Imager::Font/string>, L<Imager::Font/align>,
+L<Imager::Font::Wrap>
+
+fonts, metrics - L<Imager::Font/bounding_box>, L<Imager::Font::BBox>
+
+fonts, multiple master - L<Imager::Font/"MULTIPLE MASTER FONTS">
+
+fountain fill - L<Imager::Fill/"Fountain fills">,
+L<Imager::Filters/fountain>, L<Imager::Fountain>,
+L<Imager::Filters/gradgen>
+
+GIF files - L<Imager::Files/"GIF">
+
+GIF files, animated - L<Imager::File/"Writing an animated GIF">
+
+gradient fill - L<Imager::Fill/"Fountain fills">,
+L<Imager::Filters/fountain>, L<Imager::Fountain>,
+L<Imager::Filters/gradgen>
+
+guassian blur - L<Imager::Filter/guassian>
+
+hatch fills - L<Imager::Fill/"Hatched fills">
+
+invert image - L<Imager::Filter/hardinvert>
+
+JPEG - L<Imager::Files/"JPEG">
+
+limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
+
+lines, drawing - L<Imager::Draw/line>
+
+matrix - L<Imager::Matrix2d>,
+L<Imager::Transformations/"Matrix Transformations">,
+L<Imager::Font/transform>
+
+metadata, image - L<Imager::ImageTypes/"Tags">
+
+mosaic - L<Imager::Filter/mosaic>
+
+noise, filter - L<Imager::Filter/noise>
+
+noise, rendered - L<Imager::Filter/turbnoise>,
+L<Imager::Filter/radnoise>
+
+posterize - L<Imager::Filter/postlevels>
+
+png files - L<Imager::Files>, L<Imager::Files/"PNG">
+
+pnm - L<Imager::Files/"PNM (Portable aNy Map)">
+
+rectangles, drawing - L<Imager::Draw/box>
+
+resizing an image - L<Imager::Transformations/scale>,
+L<Imager::Transformations/crop>
+
+saving an image - L<Imager::Files>
+
+scaling - L<Imager::Transformations/scale>
+
+sharpen - L<Imager::Filters/unsharpmask>, L<Imager::Filters/conv>
+
+size, image - L<Imager::ImageTypes/getwidth>,
+L<Imager::ImageTypes/getheight>
+
+size, text - L<Imager::Font/bounding_box>
+
+text, drawing - L<Imager::Font/string>, L<Imager::Font/align>,
+L<Imager::Font::Wrap>
+
+text, wrapping text in an area - L<Imager::Font::Wrap>
+
+text, measuring - L<Imager::Font/bounding_box>, L<Imager::Font::BBox>
+
+tiles, color - L<Imager::Filter/mosaic>
+
+unsharp mask - L<Imager::Filter/unsharpmask>
+
+watermark - L<Imager::Filter/watermark>
+
+writing an image - L<Imager::Files>
+
=head1 SUPPORT
You can ask for help, report bugs or express your undying love for
where you can also find the mailing list archive.
If you're into IRC, you can typically find the developers in #Imager
-on irc.rhizomatic.net. As with any IRC channel, the participants
-could be occupied or asleep, so please be patient.
+on irc.perl.org. As with any IRC channel, the participants could be
+occupied or asleep, so please be patient.
+
+You can report bugs by pointing your browser at:
+
+ https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager
+
+Please remember to include the versions of Imager, perl, supporting
+libraries, and any relevant code. If you have specific images that
+cause the problems, please include those too.
=head1 BUGS
Imager::Expr(3), Imager::Matrix2d(3), Imager::Fountain(3)
Affix::Infix2Postfix(3), Parse::RecDescent(3)
-http://imager.perl.org/~addi/perl/Imager/
+http://imager.perl.org/
=cut