X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/626cabcc99ce19e67e9b9f409a7cf52a8654a867..e72d3bb1b80d0bce51fb59f8747122ed302bf386:/Imager.pm diff --git a/Imager.pm b/Imager.pm index b497b48f..38f7d152 100644 --- a/Imager.pm +++ b/Imager.pm @@ -493,9 +493,35 @@ sub read { if ($input{fd}) { $fd=$input{fd} }; if ( $input{type} eq 'gif' ) { - if (exists $input{data}) { $self->{IMG}=i_readgif_scalar($input{data}); } - else { $self->{IMG}=i_readgif( $fd ) } - if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read gif image'; return undef; } + my $colors; + if ($input{colors} && !ref($input{colors})) { + # must be a reference to a scalar that accepts the colour map + $self->{ERRSTR} = "option 'colors' must be a scalar reference"; + return undef; + } + if (exists $input{data}) { + if ($input{colors}) { + ($self->{IMG}, $colors) = i_readgif_scalar($input{data}); + } + else { + $self->{IMG}=i_readgif_scalar($input{data}); + } + } + else { + if ($input{colors}) { + ($self->{IMG}, $colors) = i_readgif( $fd ); + } + else { + $self->{IMG} = i_readgif( $fd ) + } + } + if ($colors) { + # we may or may not change i_readgif to return blessed objects... + ${$input{colors}} = [ map { NC(@$_) } @$colors ]; + } + if ( !defined($self->{IMG}) ) { + $self->{ERRSTR}= 'reading GIF:'._error_as_msg(); return undef; + } $self->{DEBUG} && print "loading a gif file\n"; } elsif ( $input{type} eq 'jpeg' ) { if (exists $input{data}) { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_scalar($input{data}); } @@ -617,7 +643,7 @@ sub write { $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes}); } if ( !defined($rc) ) { - $self->{ERRSTR}='unable to write gif image'; return undef; + $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef; } $self->{DEBUG} && print "writing a gif file\n"; @@ -993,6 +1019,18 @@ sub rubthrough { } +sub flip { + my $self = shift; + my %opts = @_; + my %xlate = (h=>0, v=>1, hv=>2, vh=>2); + my $dir; + return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}}; + $dir = $xlate{$opts{'dir'}}; + return $self if i_flipxy($self->{IMG}, $dir); + return (); +} + + # These two are supported for legacy code only @@ -1465,6 +1503,23 @@ The second example shows how to read an image from a scalar, this is usefull if your data originates from somewhere else than a filesystem such as a database over a DBI connection. +If you are reading from a gif image file, you can supply a 'colors' +parameter which must be a reference to a scalar. The referenced +scalar will receive an array reference which contains the colors, each +represented as an Imager::Color object. + +If you already have an open file handle, for example a socket or a +pipe, you can specify the 'fd' parameter instead of supplying a +filename. Please be aware that you need to use fileno() to retrieve +the file descriptor for the file: + + $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr; + +For writing using the 'fd' option you will probably want to set $| for +that descriptor, since the writes to the file descriptor bypass Perl's +(or the C libraries) buffering. Setting $| should avoid out of order +output. + *Note that load() is now an alias for read but will be removed later* C<$img-Ewrite> has the same interface as C. The earlier @@ -1492,6 +1547,32 @@ is sufficient: use Imager; print "@{[keys %Imager::formats]}"; +When reading raw images you need to supply the width and height of the +image in the xsize and ysize options: + + $img->read(file=>'foo.raw', xsize=>100, ysize=>100) + or die "Cannot read raw image\n"; + +If your input file has more channels than you want, or (as is common), +junk in the fourth channel, you can use the datachannels and +storechannels options to control the number of channels in your input +file and the resulting channels in your image. For example, if your +input image uses 32-bits per pixel with red, green, blue and junk +values for each pixel you could do: + + $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4, + storechannels=>3) + or die "Cannot read raw image\n"; + +Normally the raw image is expected to have the value for channel 1 +immediately following channel 0 and channel 2 immediately following +channel 1 for each pixel. If your input image has all the channel 0 +values for the first line of the image, followed by all the channel 1 +values for the first line and so on, you can use the interleave option: + + $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1) + or die "Cannot read raw image\n"; + =head2 Multi-image files Currently just for gif files, you can create files that contain more @@ -1666,8 +1747,7 @@ is 'ordered'. Possible values are: =item random -A semi-random map is used. The map is the same each time. Currently -the default (which may change.) +A semi-random map is used. The map is the same each time. =item dot8 @@ -1697,6 +1777,11 @@ diagonal line dither diagonal line dither +=item tiny + +dot matrix dither (currently the default). This is probably the best +for displays (like web pages). + =item custom A custom dither matrix is used - see tr_map @@ -1857,7 +1942,6 @@ the function return undef. Examples: =head2 Drawing Methods IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS - DOCUMENTATION OF THIS SECTION OUT OF SYNC It is possible to draw with graphics primitives onto images. Such @@ -1964,10 +2048,23 @@ To copy an image to onto another image use the C method. That copies the entire C<$logo> image onto the C<$dest> image so that the upper left corner of the C<$logo> image is at (40,20). + +=head2 Flipping images + +An inplace horizontal or vertical flip is possible by calling the +C method. If the original is to be preserved it's possible to +make a copy first. The only parameter it takes is the C +parameter which can take the values C, C, C and C. + + $img->flip(dir=>"h"); # horizontal flip + $img->flip(dir=>"vh"); # vertical and horizontal flip + $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically + =head2 Blending Images - -To put an image or a part of an image directly into another it is -best to call the C method on the image you want to add to. + +To put an image or a part of an image directly +into another it is best to call the C method on the image you +want to add to. $img->paste(img=>$srcimage,left=>30,top=>50);