Imager#
Perl bindings for Imager, the raster graphics library.
This is the Imager module, version 1.037 of the CPAN API: the same packages, methods, arguments and return values that Perl code written against Imager already expects - for the part of it that is available so far (see below).
use Imager;
my $img = Imager->new(xsize => 4, ysize => 3, channels => 4) or die Imager->errstr;
$img->setpixel(x => 1, y => 1, color => Imager::Color->new(255, 0, 0));
my $c = $img->getpixel(x => 1, y => 1);
printf "%dx%d, %d channels, pixel %s\n", $img->getwidth, $img->getheight,
$img->getchannels, join(",", $c->rgba); # 4x3, 4 channels, pixel 255,0,0,255
my @s = $img->getsamples(y => 1, x => 1, width => 1); # 255 0 0 255
my $copy = $img->copy;
$img->settag(name => 'note', value => 'hello');
What is available#
The image engine and the operations on it that are native so far: creating images of every kind below, getpixel/setpixel, getsamples/setsamples, getscanline/setscanline, copy, palettes (addcolors, getcolors, colorcount and the rest), tags, the channel mask, masked images, the colour classes, drawing (box, line, arc, circle, polygon, polypolygon, flood_fill, polybezier), fills, paste, crop, rubthrough and compose, flip, convert, map and Imager->combine, to_paletted, Imager->make_palette, getcolorcount and getcolorusage, scale, scaleX and scaleY, rotate and matrix_transform, trim and trim_rect, transform and Imager::transform2, the filters, difference and rgb_difference, the files below, and text through Imager::Font::FT2.
Not available: Imager->load_plugin, the loader for filter plugins compiled from C. It returns undef and sets $Imager::ERRSTR to “Couldn’t load plugin ‘…’”, as it does for a file that cannot be loaded. Imager’s documentation has called that interface deprecated since 0.48 (2006).
Drawing#
box, line, arc, circle and polygon draw in a colour or, where they fill an area, through a fill (below). aa => 1 anti-aliases lines, arcs, circles and outlines; filled => 0 gives the outline of a circle or an arc. A polygon is always anti-aliased, and mode => 'nonzero' fills it by the non-zero winding rule instead of the even-odd one; polypolygon takes several at once, so one can be a hole in another. flood_fill fills the region of one colour around a point, or with border everything up to that colour, and polybezier draws a Bezier curve through control points.
$img->circle(x => 50, y => 50, r => 30, color => 'red', aa => 1);
$img->arc(x => 50, y => 50, r => 40, d1 => 0, d2 => 90, filled => 0, aa => 1);
$img->polygon(points => [ [ 10, 10 ], [ 90, 30 ], [ 40, 80 ] ], color => 'green');
$img->flood_fill(x => 2, y => 2, color => 'blue') or die $img->errstr;
Where Imager differs from the other raster modules#
Imager is not a wrapper around one C library; its image engine is its own. That engine is what this module provides natively, and it is why Imager can do things the others cannot: an image may hold 8-bit, 16-bit or floating-point samples, may be paletted or direct, and may have one to four channels, in any combination. A greyscale 16-bit image and an RGBA 8-bit image are both ordinary Imager images.
Every operation works on all of them, so code written for one kind of image works on another without change.
Four kinds of image#
An image is described by three independent properties, and Imager supports the whole product of them:
Property | Values |
|---|---|
sample size | 8-bit, 16-bit, double |
storage | direct, or paletted (up to 256 colours) |
channels | 1 (grey), 2 (grey+alpha), 3 (RGB), 4 (RGBA) |
my $rgb = Imager->new(xsize => 10, ysize => 10); # 8-bit RGB
my $deep = Imager->new(xsize => 10, ysize => 10, bits => 16);
my $float = Imager->new(xsize => 10, ysize => 10, bits => 'double');
my $pal = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
my $grey = Imager->new(xsize => 10, ysize => 10, channels => 1);
Reading and writing a pixel works the same on all of them. getpixel/setpixel speak Imager::Color (bytes) or Imager::Color::Float (doubles); a 16-bit or floating-point image keeps its extra precision only if you use the float form.
Colours#
A colour is four channels. Imager::Color holds them as bytes, 0 to 255, which is what most code wants; Imager::Color::Float holds them as floating-point numbers, nominally 0 to 1, which is what a 16-bit or floating-point image needs to keep its precision.
Imager::Color->new accepts the friendly spellings - a name, an HTML hex string, a channel list:
my $red = Imager::Color->new('red');
my $red2 = Imager::Color->new('#FF0000');
my $red3 = Imager::Color->new(255, 0, 0);
my $trans = Imager::Color->new(255, 0, 0, 128);
my ($r, $g, $b, $a) = $red->rgba;
Anywhere a method takes color =>, an array reference works too and is the least ceremony for a one-off: $img->setpixel(x => 0, y => 0, color => [0, 128, 255]).
The channel mask#
$img->setmask(mask => 0x5) makes subsequent writes touch only the channels whose bit is set - channel 0 and channel 2 here. Reads ignore it. It is how you draw into one channel of an image without disturbing the others.
Errors#
Imager reports failure by returning false and leaving the reason in an error stack. Imager->errstr on the class gives the last error; $img->errstr gives that image’s. Nothing croaks for an ordinary failure, so the idiom is to check and report:
my $img = Imager->new(xsize => 10, ysize => 10) or die Imager->errstr;
Files#
PNM files (PBM, PGM and PPM, ASCII and binary, 8 and 16 bit), Windows BMP files, Targa files and raw files (type => 'raw', samples and nothing else) are read and written - the formats Imager has without any library. GIF, JPEG, PNG and TIFF are not available yet. BMP is read at 1, 4, 8, 16, 24 and 32 bits a pixel, run length encoded and with bit-field masks, and written uncompressed: 24 bits for a direct image, 1, 4 or 8 for a paletted one.
my $img = Imager->new(file => 'in.ppm') or die Imager->errstr;
$img->write(file => 'out.pgm', type => 'pnm') or die $img->errstr;
my @all = Imager->read_multi(file => 'frames.ppm');
Targa is read and written colour-mapped, direct and grey, run length encoded (compress => 1, the default) or not, with wierdpack => 1 for 15 and 16 bits a pixel and idstring for the file’s id.
Masked images#
$img->masked gives a view of a rectangle of an image, optionally written through a mask: a pixel of the view is a pixel of the image, reads see all of it, and a write lands only where the mask’s first channel is not zero. The view can be drawn into, copied and written to a file like any image.
my $mask = Imager->new(xsize => 100, ysize => 100, channels => 1);
$mask->box(filled => 1, color => 'white', xmin => 20, xmax => 79);
my $view = $img->masked(mask => $mask, left => 10, top => 10,
right => 110, bottom => 110);
$view->box(filled => 1, color => 'red'); # a red band in $img
Fills#
box and arc take a fill instead of a colour: a hash of Imager::Fill->new parameters or such an object. A fill is a solid colour, one of the 32 named hatches or a custom 8x8 one (hatch, fg, bg, dx, dy), a tiled image (image, with xoff, yoff and a matrix), or another fill made more transparent (type => 'opacity'). combine says how it meets what is already there: none, normal, multiply, dissolve, add, subtract, diff, lighten, darken, hue, saturation, value or color. A fountain fill (fountain => 'linear', radial, conical and the rest, with segments of colours as Imager::Fountain builds them) is a gradient between the points xa, ya and xb, yb; the fountain filter draws the same over a whole image.
$img->box(xmin => 10, ymin => 10, xmax => 90, ymax => 50,
fill => { hatch => 'check2x2', fg => 'red', bg => 'white' });
my $glass = Imager::Fill->new(solid => Imager::Color->new(0, 0, 255, 96),
combine => 'normal');
$img->arc(x => 50, y => 50, r => 30, fill => $glass);
One image onto another#
paste copies a rectangle as it is. rubthrough lays the source over the target by the source’s alpha channel. compose does the same with a combine mode (the names above) and an opacity, and with mask takes the coverage of each pixel from the first channel of a third image.
$img->rubthrough(src => $logo, tx => 10, ty => 10) or die $img->errstr;
$img->compose(src => $logo, tx => 10, ty => 10, combine => 'multiply',
opacity => 0.5, mask => $mask) or die $img->errstr;
setsamples writes samples of chosen channels, as 8-bit values, floating point (type => 'float') or 16-bit (type => '16bit', on a 16-bit image), and getsamples reads them in the same three forms.
An alpha channel is written over the colour of the i_background tag, black without one; pnm_write_wide_data => 1 writes a 16-bit image with 16-bit samples. Imager->set_file_limits bounds the width, height and bytes of what read accepts, and Imager->add_file_magic teaches the format detection a new signature.
Channels#
convert makes a new image whose channels are weighted sums of this one’s, by a matrix or a preset (grey, noalpha, rgb, addalpha, red, green, blue, alpha); Imager->combine makes one from a channel each of several images; map runs the samples of chosen channels through lookup tables in place, and flip mirrors the image in place.
my $grey = $img->convert(preset => 'grey') or die $img->errstr;
my $bgr = $img->convert(matrix => [ [ 0, 0, 1 ], [ 0, 1, 0 ], [ 1, 0, 0 ] ]);
my $again = Imager->combine(src => [ $r, $g, $b ]) or die Imager->errstr;
$img->map(red => [ reverse 0 .. 255 ]);
$img->flip(dir => 'h');
Scaling#
scale returns a scaled copy: by scalefactor, or to xpixels and ypixels, where type says how the two combine (max, min, nonprop). qtype picks the method: normal (a Lanczos filter), preview (nearest neighbour) or mixing (the mean of the area each pixel covers). normal and preview give an 8-bit image whatever the source holds, as in Imager; mixing keeps the depth.
my $thumb = $img->scale(xpixels => 160, ypixels => 120, type => 'min',
qtype => 'mixing') or die $img->errstr;
Rotation and matrix transforms#
rotate(right => 90) (or 180, 270) turns the image exactly; rotate(degrees => ...) or radians rotates by any angle into an image large enough to hold the result, with back for the corners. matrix_transform maps the image through a 3 x 3 matrix, such as Imager::Matrix2d builds, with bilinear interpolation. A paletted image is not interpolated.
my $turned = $img->rotate(degrees => 30, back => 'white') or die $img->errstr;
Expressions per pixel#
Imager::transform2 builds an image from an expression evaluated for every pixel, in postfix (rpnexpr) or, with Parse::RecDescent installed, infix (expr): arithmetic, comparisons, getp1 to getp3 for the pixels of up to three input images, rgb, hsv and their parts. $img->transform is the older form: two small stack programs give the source position of each pixel.
my $mirrored = Imager::transform2({ rpnexpr => 'w x - 1 - y getp1' }, $img)
or die Imager->errstr;
Filters#
$img->filter(type => ...) changes the image in place, with every filter Imager has built in: autolevels and autolevels_skew, bumpmap and bumpmap_complex, contrast, conv, fountain, gaussian and gaussian2, gradgen, hardinvert and hardinvertall, mosaic, nearest_color, noise, postlevels, radnoise, turbnoise, unsharpmask and watermark. Many work through 8-bit samples, as in Imager, so a 16-bit or double image keeps 8 bits of precision afterwards. $img->difference and rgb_difference make a new image of where two images differ.
$img->filter(type => 'autolevels') or die $img->errstr;
$img->filter(type => 'mosaic', size => 8);
Paletted images from direct ones#
to_paletted quantises an image. make_colors says where the palette comes from: mediancut (the default), addi, a fixed map (webmap, mono, gray, gray4, gray16) or none for the colors you give; max_colors bounds it. translate says how the pixels are matched to it: closest, perturb, or errdiff with an errdiff of floyd, jarvis, stucki or a custom map. Imager->make_palette makes one palette for several images, and getcolorcount and getcolorusage count the colours of an image.
my $pal = $img->to_paletted(make_colors => 'mediancut', max_colors => 16,
translate => 'errdiff') or die $img->errstr;
my $n = $img->getcolorcount(maxcolors => 256); # undef if more
The addi palette and the perturb translation use the C library’s random numbers, which Imager never seeds: the same image gives the same result every run.
Differences from upstream#
Beyond load_plugin (above), eighteen:
Where perl 5.44 with XS Imager reads freed memory: an
Imager::ImgRaworImager::IOused after itsDESTROYcroaks “not a live Imager::ImgRaw” (or “Imager::IO”) (t/64-auto-ffi/414-imager-or-better.t).Imager::io_slurpof an I/O object that is not a buffer chain croaks “io_slurp: called on a source that is not from a bufchain”. Imager 1.037 ends the whole program there, silently and with exit status 0.Reading a row of a paletted image as floating point colours (
getscanline(type => 'float')) returns its colours and leaves the image alone. Imager 1.037 writes where it should read there (image.ci_glinf_fpcallsi_plinon an uninitialised buffer): the row comes back as whatever was in memory, and the image is overwritten with it and turned into a direct colour image.A grey image with an alpha channel written as BMP has its grey applied over the background by its own alpha. Imager 1.037 reads the wrong samples there (paste.im
i_gsamp_bgasks for 2 a pixel and reads 4): every pixel takes its neighbour’s grey as alpha and half the row is whatever was in memory.A masked image keeps its target and its mask alive, an image fill its image and an opacity fill its base fill. In Imager 1.037 that is done by
$img->maskedandImager::Fill->new, which store them in the result; the objects themselves hold bare pointers, so one made withImager::i_img_masked_neworImager::i_new_fill_imagedirectly reads freed memory once the other is gone.pastewith a source rectangle that starts left of or above the source image writes black for the part outside it. Imager 1.037 writes whatever was in the memory it had just allocated.The
huecombine mode leaves a grey pixel of an image without an alpha channel as it is. Imager 1.037 changes it to a colour that differs from run to run (it reads an alpha the image does not have).A custom hatch given as a string shorter than 8 bytes has empty rows for the missing bytes; Imager 1.037 takes them from whatever follows the string in memory.
An image fill with a
matrixdrawn into a 16-bit or double image from a source without an alpha channel draws the source. In Imager 1.037 that fill comes out black.A polygon with a coordinate beyond 134 million pixels keeps its shape. Imager 1.037 converts such a coordinate to an
intit does not fit in; on x86-64 the vertex lands far to the left of the image instead of far to the right.composewith a rectangle the target clips and a negative source or mask offset larger than what is left draws nothing and succeeds. Imager 1.037 prints “Out of memory” and aborts the program there.The fountain filter called as
Imager::i_fountainwith a super-sampling number it does not know draws without super-sampling, with a negative sample count draws nothing, and with segments that are not an array croaks. Imager 1.037 crashes in all three. A fountain fill none of whose samples has a colour draws transparent black where Imager draws what was in memory.getsamples(type => '16bit')of a negative sample in a double image gives 0. Imager 1.037 converts the negative number to an unsigned one, which on x86-64 gives a value near 4294967295.to_palettedwithmake_colors => 'addi'makes opaque colours. Imager 1.037 sets only their red, green and blue, so the palette of a four channel image has an alpha that is whatever was in memory.transformandtransform2start from black and from empty registers, end a program that reaches outside its registers or its code, clamprgb()of a number beyond the int range, and refuse a missing input image or a channel count outside 1 to 4. Imager 1.037 computes from memory it never set in the first cases and crashes in the last two.The
postlevelsfilter withlevels => 0,autolevels_skewon a channel whose range comes out empty, andmosaicwith asizeof 0 or less leave the image as it is. Imager 1.037 dies of a division by zero in the first two and never returns from the third. A negative bump map channel is refused; Imager reads outside the colour.Imager::i_gradgenwith a distance measure other than 0, 1 or 2 croaks. Imager 1.037 ends the program with exit status 3.Imager->set_out_of_memory_handler($code)stores and returns the handler, but it is never called. An image whose pixel storage cannot be allocated fails with “Out of memory allocating image surface”, as upstream; running out of memory for anything smaller ends the process, as upstream does when no handler is set.
Modules#
Imager::Color- Color handling for Imager.Imager::Expr- implements expression parsing and compilation for the expression evaluation engine used by Imager::transform2()Imager::ExtUtils- functions handy in writing Imager extensionsImager::Fill- Imager::Fill - general fill typesImager::Font- Font handling for Imager.Imager::Fountain- Imager::Fountain - a class for building fountain fills suitable for use by the fountain filter.Imager::Matrix2d- Imager::Matrix2d - simple wrapper for matrix constructionImager::Regops- generated information about the register based virtual machineImager::Test- common functions used in testing ImagerImager::Transform- Imager::Transform - a library of register machine image transformationsImager::TrimColorList- represent a list of color ranges for Imager’s trim() method.
Functions#
Library information#
i_list_formats#
The image file formats this build can read and write, as a list of short names such as "png" and "jpeg".
Errors#
i_clear_error#
Discard any pending error.
i_push_error#
Add a message to the error stack.
i_errors#
The pending errors, newest first, each as an array reference [$message, $code]. Imager->errstr is built from this.