BEGIN {
require Exporter;
@ISA = qw(Exporter);
- $VERSION = '0.53';
+ $VERSION = '0.59';
eval {
require XSLoader;
XSLoader::load(Imager => $VERSION);
$self->_set_error("resulting image would have no content");
return;
}
-
+ if( $r < $l or $b < $t ) {
+ $self->_set_error("attempting to crop outside of the image");
+ return;
+ }
my $dst = $self->_sametype(xsize=>$r-$l, ysize=>$b-$t);
i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
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";
+ warn "to_rgb8() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
return;
}
return $result;
}
+# convert a paletted (or any image) to an 8-bit/channel RGB images
+sub to_rgb16 {
+ my $self = shift;
+ my $result;
+
+ unless (defined wantarray) {
+ my @caller = caller;
+ warn "to_rgb16() called in void context - to_rgb8() returns the converted image at $caller[1] line $caller[2]\n";
+ return;
+ }
+
+ if ($self->{IMG}) {
+ $result = Imager->new;
+ $result->{IMG} = i_img_to_rgb16($self->{IMG})
+ or undef $result;
+ }
+
+ return $result;
+}
+
sub addcolors {
my $self = shift;
my %opts = (colors=>[], @_);
sub _get_reader_io {
my ($self, $input) = @_;
- if ($input->{io}) {
- return $input->{io}, undef;
- }
+ if ($input->{io}) {
+ return $input->{io}, undef;
+ }
elsif ($input->{fd}) {
return io_new_fd($input->{fd});
}
sub _get_writer_io {
my ($self, $input, $type) = @_;
- if ($input->{fd}) {
+ if ($input->{io}) {
+ return $input->{io};
+ }
+ elsif ($input->{fd}) {
return io_new_fd($input->{fd});
}
elsif ($input->{fh}) {
return $self;
}
+ my $allow_incomplete = $input{allow_incomplete};
+ defined $allow_incomplete or $allow_incomplete = 0;
+
if ( $input{'type'} eq 'tiff' ) {
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 );
+ $self->{IMG}=i_readtiff_wiol( $IO, $allow_incomplete, $page );
if ( !defined($self->{IMG}) ) {
$self->{ERRSTR}=$self->_error_as_msg(); return undef;
}
}
if ( $input{'type'} eq 'pnm' ) {
- $self->{IMG}=i_readpnm_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
+ $self->{IMG}=i_readpnm_wiol( $IO, $allow_incomplete );
if ( !defined($self->{IMG}) ) {
$self->{ERRSTR}='unable to read pnm image: '._error_as_msg();
return undef;
}
if ( $input{'type'} eq 'bmp' ) {
- $self->{IMG}=i_readbmp_wiol( $IO );
+ $self->{IMG}=i_readbmp_wiol( $IO, $allow_incomplete );
if ( !defined($self->{IMG}) ) {
$self->{ERRSTR}=$self->_error_as_msg();
return undef;
my $page = $input{'page'};
defined $page or $page = 0;
$self->{IMG} = i_readgif_single_wiol( $IO, $page );
- if ($input{colors}) {
+ if ($self->{IMG} && $input{colors}) {
${ $input{colors} } =
[ i_getcolors($self->{IMG}, 0, i_colorcount($self->{IMG})) ];
}
$self->_set_opts(\%input, "bmp_", $self)
or return undef;
if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
- $self->{ERRSTR}='unable to write bmp image';
+ $self->{ERRSTR} = $self->_error_as_msg;
return undef;
}
$self->{DEBUG} && print "writing a bmp file\n";
}
}
else {
- $ERRSTR = "Sorry, write_multi doesn't support $type yet";
- return 0;
+ if (@images == 1) {
+ unless ($images[0]->write(%$opts, io => $IO, type => $type)) {
+ return 1;
+ }
+ }
+ else {
+ $ERRSTR = "Sorry, write_multi doesn't support $type yet";
+ return 0;
+ }
}
}
return;
}
}
+ else {
+ my $img = Imager->new;
+ if ($img->read(%opts, io => $IO, type => $type)) {
+ return ( $img );
+ }
+ }
$ERRSTR = "Cannot read multiple images from $type files";
return;
sub scale {
my $self=shift;
- my %opts=(scalefactor=>0.5,'type'=>'max',qtype=>'normal',@_);
+ my %opts=('type'=>'max',qtype=>'normal',@_);
my $img = Imager->new();
my $tmp = Imager->new();
-
- my $scalefactor = $opts{scalefactor};
+ my ($x_scale, $y_scale);
unless (defined wantarray) {
my @caller = caller;
return undef;
}
+ if ($opts{'xscalefactor'} && $opts{'yscalefactor'}) {
+ $x_scale = $opts{'xscalefactor'};
+ $y_scale = $opts{'yscalefactor'};
+ }
+ elsif ($opts{'xscalefactor'}) {
+ $x_scale = $opts{'xscalefactor'};
+ $y_scale = $opts{'scalefactor'} || $x_scale;
+ }
+ elsif ($opts{'yscalefactor'}) {
+ $y_scale = $opts{'yscalefactor'};
+ $x_scale = $opts{'scalefactor'} || $y_scale;
+ }
+ else {
+ $x_scale = $y_scale = $opts{'scalefactor'} || 0.5;
+ }
+
# work out the scaling
if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
my ($xpix, $ypix)=( $opts{xpixels} / $self->getwidth() ,
$opts{ypixels} / $self->getheight() );
if ($opts{'type'} eq 'min') {
- $scalefactor = _min($xpix,$ypix);
+ $x_scale = $y_scale = _min($xpix,$ypix);
}
elsif ($opts{'type'} eq 'max') {
- $scalefactor = _max($xpix,$ypix);
+ $x_scale = $y_scale = _max($xpix,$ypix);
+ }
+ elsif ($opts{'type'} eq 'nonprop' || $opts{'type'} eq 'non-proportional') {
+ $x_scale = $xpix;
+ $y_scale = $ypix;
}
else {
$self->_set_error('invalid value for type parameter');
return undef;
}
} elsif ($opts{xpixels}) {
- $scalefactor = $opts{xpixels} / $self->getwidth();
+ $x_scale = $y_scale = $opts{xpixels} / $self->getwidth();
}
elsif ($opts{ypixels}) {
- $scalefactor = $opts{ypixels}/$self->getheight();
+ $x_scale = $y_scale = $opts{ypixels}/$self->getheight();
}
elsif ($opts{constrain} && ref $opts{constrain}
&& $opts{constrain}->can('constrain')) {
# we've been passed an Image::Math::Constrain object or something
# that looks like one
+ my $scalefactor;
(undef, undef, $scalefactor)
= $opts{constrain}->constrain($self->getwidth, $self->getheight);
unless ($scalefactor) {
$self->_set_error('constrain method failed on constrain parameter');
return undef;
}
+ $x_scale = $y_scale = $scalefactor;
}
if ($opts{qtype} eq 'normal') {
- $tmp->{IMG} = i_scaleaxis($self->{IMG}, $scalefactor, 0);
+ $tmp->{IMG} = i_scaleaxis($self->{IMG}, $x_scale, 0);
if ( !defined($tmp->{IMG}) ) {
$self->{ERRSTR} = 'unable to scale image';
return undef;
}
- $img->{IMG}=i_scaleaxis($tmp->{IMG}, $scalefactor, 1);
+ $img->{IMG}=i_scaleaxis($tmp->{IMG}, $y_scale, 1);
if ( !defined($img->{IMG}) ) {
$self->{ERRSTR}='unable to scale image';
return undef;
return $img;
}
elsif ($opts{'qtype'} eq 'preview') {
- $img->{IMG} = i_scale_nn($self->{IMG}, $scalefactor, $scalefactor);
+ $img->{IMG} = i_scale_nn($self->{IMG}, $x_scale, $y_scale);
if ( !defined($img->{IMG}) ) {
$self->{ERRSTR}='unable to scale image';
return undef;
}
return $img;
}
+ elsif ($opts{'qtype'} eq 'mixing') {
+ my $new_width = int(0.5 + $self->getwidth * $x_scale);
+ my $new_height = int(0.5 + $self->getheight * $y_scale);
+ $new_width >= 1 or $new_width = 1;
+ $new_height >= 1 or $new_height = 1;
+ $img->{IMG} = i_scale_mixing($self->{IMG}, $new_width, $new_height);
+ unless ($img->{IMG}) {
+ $self->_set_error(Imager->_error_as_meg);
+ return;
+ }
+ return $img;
+ }
else {
$self->_set_error('invalid value for qtype parameter');
return undef;
if (ref $x && ref $y) {
unless (@$x == @$y) {
$self->{ERRSTR} = 'length of x and y mismatch';
- return undef;
+ return;
}
+ my $set = 0;
if ($color->isa('Imager::Color')) {
for my $i (0..$#{$opts{'x'}}) {
- i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color);
+ i_ppix($self->{IMG}, $x->[$i], $y->[$i], $color)
+ or ++$set;
}
}
else {
for my $i (0..$#{$opts{'x'}}) {
- i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color);
+ i_ppixf($self->{IMG}, $x->[$i], $y->[$i], $color)
+ or ++$set;
}
}
+ $set or return;
+ return $set;
}
else {
if ($color->isa('Imager::Color')) {
- i_ppix($self->{IMG}, $x, $y, $color);
+ i_ppix($self->{IMG}, $x, $y, $color)
+ and return;
}
else {
- i_ppixf($self->{IMG}, $x, $y, $color);
+ i_ppixf($self->{IMG}, $x, $y, $color)
+ and return;
}
}
unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
my %input=('x'=>0, 'y'=>0, @_);
- $input{string}||=$input{text};
+ defined($input{string}) or $input{string} = $input{text};
unless(defined $input{string}) {
$self->{ERRSTR}="missing required parameter 'string'";
to_paletted() - L<Imager::ImageTypes/to_paletted>
+to_rgb16() - L<Imager::ImageTypes/to_rgb16>
+
to_rgb8() - L<Imager::ImageTypes/to_rgb8>
transform() - L<Imager::Engines/"transform">
libraries, and any relevant code. If you have specific images that
cause the problems, please include those too.
-=head1 BUGS
+If you don't want to publish your email address on a mailing list you
+can use CPAN::Forum:
+
+ http://www.cpanforum.com/dist/Imager
+
+You will need to register to post.
+
+=head1 CONTRIBUTING TO IMAGER
+
+=head2 Feedback
+
+I like feedback.
+
+If you like or dislike Imager, you can add a public review of Imager
+at CPAN Ratings:
-Bugs are listed individually for relevant pod pages.
+ http://cpanratings.perl.org/dist/Imager
+
+This requires a Bitcard Account (http://www.bitcard.org).
+
+You can also send email to the maintainer below.
+
+If you send me a bug report via email, it will be copied to RT.
+
+=head2 Patches
+
+I accept patches, preferably against the main branch in subversion.
+You should include an explanation of the reason for why the patch is
+needed or useful.
+
+Your patch should include regression tests where possible, otherwise
+it will be delayed until I get a chance to write them.
=head1 AUTHOR
-Arnar M. Hrafnkelsson and Tony Cook (tony@imager.perl.org) among
-others. See the README for a complete list.
+Tony Cook <tony@imager.perl.org> is the current maintainer for Imager.
+
+Arnar M. Hrafnkelsson is the original author of Imager.
+
+Many others have contributed to Imager, please see the README for a
+complete list.
=head1 SEE ALSO