It’s no secret that I don’t like PHP. In fact, I dedicated an entire article to explaining just why I don’t like PHP last year. Recently I’ve found another reason to dislike PHP. The GD image manipulation libraries SUCK! They are so insanely and needlessly complex. All I wanted to do was write a simple command-line script to read in a folder and edit each JPEG image in the folder to resize it, insert a Creative Commons logo, and the URL to my website. I’m currently working on uploading some of my photography to my website and doing this manually for all my photos is just not an option, it would take forever! So, I started writing a PHP script because I know PHP can do these things thanks to the DB libs. That turned out to be a bad idea so I ran home to Perl πŸ™‚

[tags]Perl, PHP, GD Libs, Image Magick[/tags]

I got about 30 lines into the PHP code, realised it would be a total mess and gave up. The complexity of doing even the most simple things in the GD libs is astounding. Surely, you’d expect to be able to re-size an image with a one-liner. Not with GD! Inserting one image into another, also not a one liner. Adding in text, DEFINITELY not a one liner. At that stage I’d had enough. I went for Perl and the Image Magick binaries that I had installed anyway. In about half the time I’d already dedicated to my very incomplete PHP solution I threw together a working Perl solution. The real work is done in this very small Perl module:

package WebifyImages;

# static variables
$WebifyImages::CC_ICON = '~/scripts/webifyImages/cc80x15.png';
$WebifyImages::URL_FONT = '~/scripts/webifyImages/hanshand.ttf';

# function to addin the watermark image
# arguments: the file names to modify
sub insertCCIcon{
  print "\nInserting CC Icon:\n";
  print "------------------\n\n";
  foreach my $image (@_){
    print "processing file $image\n";
    `composite -gravity southwest -geometry +5+5  ${WebifyImages::CC_ICON} $image $image`;
  }
}

# function to add in the URL
# arguments: the file names to modify
sub insertUrl{
  print "\nInserting URL:\n";
  print "--------------\n\n";
  foreach my $image(@_){
    print "processing file $image\n";
    `convert $image -fill white -pointsize 17 -font ${WebifyImages::URL_FONT} -gravity southeast  -annotate +7-3 'www.bartbusschots.ie' $image`;
  }
}

# function to re-size images
# arguments: the file names to modify
sub resizeImages{
  print "\nResizing Images:\n";
  print "----------------\n\n";
  foreach my $image(@_){
    print "processing file $image\n";
    `mogrify -size 1024x1024 -thumbnail 800x800 $image`;
  }
}

# function to add a credit into an image
# Arguments:
# 1) the image name
# 2) the name to credit
sub insertCredit{
  my $image = shift;
  my $credit = shift;
  print "Crediting $credit on the image $image\n";
  `convert $image -fill white -pointsize 17 -font ${WebifyImages::URL_FONT} -gravity southeast -annotate +7+18 'Credit: $credit' $image`;

}

my $perl_is_dumb = 1;

To actually invoke this functionality on a directory I write the following very small script:

#!/usr/bin/perl

use lib '/Users/bart/scripts/webifyImages';

use strict;
use WebifyImages;

# Script to webify a folder of images

# print a warning
print <<endl;

WARNING WARNING WARNING

This script will modify all .jpg files in this folder!

Are you sure you want to continue? (y/n)
endl
unless(<> =~ m/y/i){
  exit;
}

# get the images to modify
my @images = <./*.jpg>;

WebifyImages::resizeImages(@images);
WebifyImages::insertCCIcon(@images);
WebifyImages::insertUrl(@images);

Because some of my older images were already the right size and already had my name on them I also wrote another simple little script which uses the same module to only insert the CC icon:

#!/usr/bin/perl

use lib '/Users/bart/scripts/webifyImages';
use strict;
use WebifyImages;

print <<endl;

WARNING WARNING WARNING

This script will modify all .jpg files in this folder!

Are you sure you want to continue? (y/n)
endl
unless(<> =~ m/y/i){
  exit;
}

# get the images to modify
my @images = <./*.jpg>;

WebifyImages::insertCCIcon(@images);

Finally, a few of the images in my photo gallery were taken by other family members using my camera so it seems only fair to credit them, hence this other simple little script:

#!/usr/bin/perl

use lib '/Users/bart/scripts/webifyImages';

use strict;
use WebifyImages;

# Script to insert a credit into an image

# get arg
my $image = $ARGV[0];
my $credit = $ARGV[1];
unless ($image){
  print "ERROR: must supply the path to the image to credit and the name to credit as arguments.\n\n";
  exit;
}

# print a warning
print <<endl;

WARNING WARNING WARNING

This script will the image $image to insert a credit to $credit

Are you sure you want to continue? (y/n)
endl
unless(<STDIN> =~ m/y/i){
  exit;
}

#do it
WebifyImages::insertCredit($image, $credit);

The things to note from all this is how simple the code is, how easy it is to understand, and how much Perl can do in one line. That contrasts very strongly with PHP and it’s GD libs!