CPAN has some very interesting Perl module which allow to manipulate images, that is: convert between various graphic formats, resize, rotate, regulate contrast, colors, add primitives, watermarks, and all the such. Imager is one of them, and it’s quite interesting as it’s stable, easy to use, powerful, and well enough documented.

I created a little program, bdtouch, which makes use of some of the features of Imager. You can download the Perl source code here, or you can read on if you’re interested in the explanation of some of its parts.

Let’s start from the very beginning of the program, that is the part which gets the command line parameters:

my %args;
GetOptions(
    \%args,
    'src=s',        'tgt=s',    'action=s',
    'verse=s',      'size=i',
    'degrees=f',
    'left=i',       'top=i',    'width=i',  'height=i',
    'intensity=f',  'stddev=f',
);

Here the Getopt::Long module is used; it is included in the core Perl distribution, so there’s no need for CPAN this time. Modules such as this are not used so often, as most coders tend to rely on @ARGV directly: this is a mistake, because parsing parameters directly is long, boring, and error prone. Getopt::Long allows you to automatically fetch parameters in POSIX style:

./bdtouch.pl --src=myfile.jpg --tgt=myfile.png --action=rotate --degrees=-75

There could also be a space instead of an equals sign between the parameter name and the value: the parser autodetects that. The required format of every parameter can be easily specified directly via the GetOptions() function: intensity=f means that intensity is a floating point number, src=s means that src is a string, and so on.

Let’s now take a look at image reading and writing:

# Open source file
$img->open( file => $args{src} )
    or die "Error opening source file: ".$img->errstr;

# Other code

# Save destination file
$img->write( file => $args{tgt} )
	or die 'Error saving file: '.$img->errstr;

The open() method of an Imager object accepts a file name, autodetects the format depending on the file extension, and reads it. You can then save it as a new file: if you change the extension, the format will change as well, so in just about 5 lines you have a full-featured graphical format converter. I’m saying full-featured because you can pass extra parameters to the write() method. For instance you can say:

$img->write( file=>'myimage.jpg', jpegquality=>65 );

and this will save a Jpeg with the requested compression factor. Depending on the format, several options are availale.

So you want to scale an image? Nothing easier:

my $newimg = $img->scale( xpixels => $args->{size} );

This code will create a new object with the same image, scaled to $args->{size} pixels of width. The aspect ratio is always maintained, and you can use ypixels instead of xpixels to change the height instead of the width.

Cropping is one of the most requested features, especially for images uploaded via web by users who are unable to use a graphic program. So you could add a cropping feature to you web application (even though you’ll have to hack JavaScript hard to make it user-friendly) by starting out of this code:

my $newimg = $img->crop(
    left    => $args->{left},
    top     => $args->{top},
    width   => $args->{width},
    height  => $args->{height},
);

This crops from left,top for width,height pixels.

Regulation of contrast is another must:

my $newimg = $img->filter(
    type        => 'contrast',
    intensity   => $args->{intensity},
);

An intensity (real number) lower than 1.0 reduces the contrast, whily an intensity higher than 1.0 increases it.

If you take a look at the entire program, it uses the features shown here and some others. It’s not perfect, especially as far as error check is concerned: only a basic one is implemented, but that was not the point of this demonstration code.

There’s a lot more if you dig in Imager. You can change any color components, convert the image to grey, and do anything you like with colors. You can write text and draw shapes. Take a look at the cookbook included in the documentation: even though incomplete, it shows many of the exciting features of this module.

Click here to download the full source code of the bdtouch program.