NAME
Imager - Perl extension for Generating 24 bit Images
SYNOPSIS
use Imager;
init(); $img = Imager->new(); $img->open(file=>'image.ppm',type=>'ppm') || print "failed: ",$img->{ERRSTR},"\n"; $scaled=$img->scale(xpixels=>400,ypixels=>400); $scaled->write(file=>'sc_image.ppm',type=>'ppm') || print "failed: ",$scaled->{ERRSTR},"\n";
DESCRIPTION
Imager is a module for creating and altering images - It is not meant as a replacement or a competitor to ImageMagick or GD. Both are excellent packages and well supported.
Why a new module? Compiling PerlMagick has been more than trivial for me, and it lacks drawing functions. GD.pm has those but only does gif and png. I like studying graphics, so why not let others in a similar situation benefit? The basis for this module is code written to preprocess remote sensing data.
Class interface
Almost all functions take the parameters in the hash fashion. Example:
$img->open(file=>'lena.png',type=>'png');
There are a few exceptions to this.
Basics
An Image object is created with $img = Imager->new()
Should this fail for some reason an explanation can be found in $Imager::ERRSTR
usually error messages are stored in $img->{ERRSTR}
, but since no object is created this is the only way to give back errors. $Imager::ERRSTR
is also used to report all errors not directly associated with an image object. Examples:
$img=Imager->new(); # This is an empty image it's size is 0 by 0
$img->open(file=>'lena.png',type=>'png'); # this initializes from file
or if you want to start clean:
$img=Imager->new(xsize=>400,ysize=>300,channels=>4);
The latter example creates a completely black image of width 400 and height 300 and 4 channels.
To create a color object call the function i_color_new, $color=i_color_new($r,$g,$b,$a)
. The parameters are all from 0 to 255 and are all converted to integers. Each is the red, green, blue, and alpha component of the color respectively. This object can then be passed to functions that require a color parameter.
Loading and saving images
$img->open()
has two parameters, 'file' and 'type', for type 'raw' two extra parameters are necessary 'xsize' and 'ysize', if the 'channel' parameter is omitted for 'raw' it is assumed to be 3. Gif and Png images that have a palette are converted to 24 bit when read. Grayscale jpegs are still 1 channel images in memory though. For jpeg images the iptc header information (stored in the APP13 header) is avaliable to some degree. You can get the raw header with $img->{IPTCRAW}
, but you can also retrieve the most basic information with %hsh=$img->parseiptc()
as always patches are welcome.
$img->write
has the same interface as open()
, for jpeg quality can be adjusted via the 'jpegquality' parameter (0-100). The number of colorplanes in gifs are set with 'gifplanes' and should be between 1 (2 color) and 8 (256 colors). It is also possible to choose between two quantizing methods with the parameter gifquant. If set to mc it uses the mediancut algorithm from either giflibrary. If set to lm it uses a local means algorithm. It is then possible to give some extra settings. lmdither is the dither deviation amount in pixels (manhattan distance). lmfixed can be an array ref who holds an array of i_color objects.
Image Methods
box arc
The Imager object have several methods to operate on the images, here is a reference oriented list:
$img->polyline(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2],[$x3,$y3]],color=>$red);
$img->polyline(x=>[$x0,$x1,$x2,$x3],y=>[$y0,$y1,$y2,$y3],antialias=>1);
polyline is used to draw multilple lines between a series of points. The point set can either be specified as an arrayref to an array of array references (where each such array represents a point. The other way is to specify two arrayreferences
Filters
A special image method is the filter method. An example is:
$img->filter(type=>'autolevels');
This will call the autolevels filter. Here is a list of the filters that are always avaliable in Imager. This list can be obtained by running the filterlist.perl script that comes with the module source.
Filter Arguments
turbnoise
autolevels lsat(0.1) usat(0.1) skew(0)
radnoise
noise amount(3) subtype(0)
contrast intensity
hardinvert
The default values are in parenthesis. All parameters must have some value but if a parameter has a default value it may be omitted when calling the filter function.
Text rendering
So far there are only the functional interface is implemented for text rendering.
Transformations
Another special image method is transform. It can be used to generate warps and rotations and such features. It can be given the operations in postfix notation or the module Affix::Infix2Postfix can be used. Look in the test case t/t55trans.t for an example.
Internals
An image object is a wrapper around the raw handle to an image. It is stored in the IMG value of the object hash. When Imager->new() is called the IMG member is set to undef by default but if you give it arguments like $img=Imager->new(xsize=>100,ysize=>100); then it will return a 3 channel image of size 100 x 100..
$img->getwidth() and $img->getheight() are used to get the dimensions of the image. $img->getmask() and $img->setmask() are used to get/set the channel mask of the image.
To scale an image so porportions are maintained use the $img->scale() method. if you give either a xpixels or ypixels parameter they will determine the width or height respectively. If both are given the one resulting in a larger image is used. example: $img is 700 pixels wide and 500 pixels tall.
$img->scale(xpixels=>400); # 400x285
$img->scale(ypixels=>400); # 560x400
$img->scale(xpixels=>400,ypixels=>400); # 560x400
$img->scale(xpixels=>400,ypixels=>400,type=>min); # 400x285
$img->scale(scalefactor=>0.25); 175x125 $img->scale(); # 350x250
if you want to create low quality previews of images you can pass qtype=>'preview' to scale and it will use nearest neighbor sampling instead of filtering. It is much faster but also generates worse looking images - especially if the original has a lot of sharp variations and the scaled image is by more than 3-5 times smaller than the original.
If you need to scale images per axis it is best to do it simply by calling scaleX and scaleY. You can pass either 'scalefactor' or 'pixels' to both functions.
Plugins
It is possible to add filters to the module without recompiling the module itself. This is done by using DSOs (Dynamic shared object) avaliable on most systems. This way you can maintain our own filters and not have to get me to add it, or worse patch every new version of the Module. Modules can be loaded AND UNLOADED at runtime. This means that you can have a server/daemon thingy that can do something like:
load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
%hsh=(a=>35,b=>200,type=>lin_stretch);
$img->filter(%hsh);
unload_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
$img->write(type=>'ppm',file=>'testout/t60.jpg')
|| die "error in write()\n";
Someone decides that the filter is not working as it should - dyntest.c modified and recompiled.
load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
$img->filter(%hsh);
An example plugin comes with the module - Please send feedback to addi@umich.edu if you test this.
Functional interface
Use only if you cannot do what you need to do with the OO interface. This is mostly intended for people who want to develop the OO interface or the XS part of the module.
$bool = i_has_format($str);
$colref = i_color_set($colref,$r,$g,$b,$a);
$imref = i_img_empty($imref,$x,$y);
$imref = i_img_empty_ch($imref,$x,$y,$channels);
@iminfo = i_img_info($imref);
i_img_setmask($imref,$channel_mask);
$ch_msk = i_img_getmask($imref);
i_draw($imref,$x1,$y1,$x2,$y2,$colref);
i_box($imref,$x1,$y1,$x2,$y2,$colref);
i_box_filled($imref,$x1,$y1,$x2,$y2,$colref);
i_arc($imref,$x,$y,$rad,$deg1,$deg2,$colref);
i_copyto($imref,$srcref,$x1,$y1,$x2,$y2,$tx,$ty,
$trans_cl_ref);
i_rubthru($imref,$srcref,$tx,$ty);
$imref = i_scaleaxis($imref,$scale_factor,$axis);
i_gaussian($imref,$stdev);
i_conv($imref,$arrayref,$array_len);
i_img_diff($imref1,$imref2);
i_init_fonts();
i_t1_set_aa($level);
i_t1_cp($imref,$xb,$yb,$channel,$fontnum,
$pts,$str,$strlen,$align);
i_t1_text($imref,$xb,$yb,$colorref,
$fontnum,$pts,$str,$strlen,$align);
i_tt_set_aa($level);
i_tt_cp($imref,$xb,$yb,$channel,$fontname,
$pts,$str,$strlen,$align);
i_tt_text($imref,$xb,$yb,$colorref,
$fontname,$pts,$str,$strlen,$align);
@bbox = i_t1_bbox($fontnum,$pts,$str,$strlen);
$imref = i_readjpeg($imref,$fd);
i_writejpeg($imref,$fd,$qfactor);
$imref = i_readpng($imref,$fd);
i_writepng($imref,$fd);
$imref = i_readgif($imref,$fd);
i_writegif($imref,$fd,$planes,$lmdither,$lmfixed);
i_writegifmc($imref,$fd,$planes);
$imref = i_readppm($imref,$fd);
i_writeppm($imref,$fd);
i_readraw($imref,$fd,$xsize,$ysize,$datachannels,
$storechannels,$interleave);
i_writeraw($imref,$fd);
AUTHOR
Arnar M. Hrafnkelsson, addi@umich.edu
SEE ALSO
perl(1). http://www.eecs.umich.edu/~addi/perl/Imager/