featured computer 850

Perl – Image Manipulation with Image Magick

Note:The rename script on this page gives files all the same names with different numbers appended. I have a separate script if you want to rename a jpg by timestamp.

Summary

Here are a couple of perl scripts that run on linux machines with perl 5 or better installed. I’ve found them very useful for processing digital photos: There is one for renaming a directory full of photos and another for resizing, creating thumbnails and annotating photos, all at once. The perl scripts use ImageMagick. You can just execute the ImageMagick commands at the command line. Cool.

To execute any of the scripts:

  1. Save the files with “.pl” extension instead of “.txt”.
  2. You can edit them with a text editor as needed.
  3. Put the script in a directory with all the files you want to change (and only the files you want to change).
  4. Open a terminal window and browse to the target directory
  5. Type “perl file_name.pl” at the command prompt.

Perl Renaming Files

The perl script for renaming files is customized for my digital camera, where the files always end in “.JPG”, but you can easily change this. When you run it, it will ask for a “base name”. This is the beginning of all the file names, which are then followed by a dash and a series of numbers from 1 to 999. For example, instead of “DSC0456.JPG” and “DSC0457.JPG”, the files will be named “ireland-001.jpg”, “ireland-002.jpg”, “ireland-003.jpg”,… which helps people searching for photos find the relevant subject matter. The perl script also creates a text file called “base_name-sources.txt” that keeps a record of what picture was changed to what name.

#!/usr/bin/perl -w
#2004-10 http://kimbriggs.com

#Initialize counter
$i = 1;

#Get the new base name of photos
print "Enter the base name for the photos (no extension): ";
chomp($basename = <>);

#Load all jpgs into an array.  Remove trailing line feed.
@pix = `ls *.JPG *.jpg`;

foreach $pix (@pix) {
   chomp $pix;

   if ($i < 10)   {$newname = $basename."-00"."$i".".jpg";}
   elsif (($i >= 10) && ($i < 100))	{$newname = $basename."-0"."$i".".jpg";}
   elsif (($i >=100) && ($i < 1000))	{$newname = $basename."-"."$i".".jpg";}
   else {warn "Number of files out of range.";}

   #Use system command to rename file.
   system 'mv', $pix, $newname;

   #Create a log file to track changes.
   $logname = $basename."-sources.txt";
   open(FILEHAND,">>$logname") or die "Can't append to $logname \n";
   print FILEHAND $newname." was ".$pix."\n";

   $i = $i+1
}
close(FILEHAND);

Perl Resizing Photos (jpegs)

The perl script for resizing photos reduces the photo by and places a tagline / watermark on it to identify the source. It also creates a subdirectory called “thumbs” and creates thumbnails in it. My originals are 2304×1728 pixels, so the photos are 640×480 and the thumbs are 192×144 pixels. In addition to changing the percentages in the scripts, you can also state an explicit size in the “convert -sample” command, such as “640×480”. The default behavior is to keep the original aspect ratio, so you might not get exactly both numbers. To find out what the numbers mean in drawing the round rectangle, look up “man imagemagick” at the command line (spacebar=forward, q=quit). Updated 2008: Now you can get the thumbnails with watermarks all in a single script.

#!/usr/bin/perl -w
#2008-03   http://kimbriggs.com
#
#For original photos that are 2304x1728 pixels.  Change percentages accordingly.
#
#Reduces all *.jpg photos 27.8% in current directory puts tagline on it
#Creates thumbnails with same name at 8.33% in subdirectory "thumbs"
#These sizes are for the "4 megapixel - fine" setting on Fuji F440.
#

#Create a directory for the thumbnails.
`mkdir thumbs`;

#Load all jpgs into an array.  Remove trailing line feed.
@pix = `ls -1 *.jpg`;

foreach $pix (@pix) {
   chomp $pix;

   #Make the thumbnail in the thumbs directory
   `convert -sample 8.333%x8.333% $pix thumbs/$pix`;
   
   #Resize by percent because should be rotated already
   `convert -sample 27.78%x27.78% $pix $pix`;

   #Annotate the image with a web address.  Upper left always works.
   `convert -fill black -draw 'roundRectangle 10,10 213,32 5,5' $pix $pix`;
   `convert -font Helvetica -fill white -pointsize 20 -draw 'text 15,27 "BIG_TAG"' $pix $pix`;

   #Identify is returning a new line AND carriage return (or somethin), so chomp and chop
   #Latest version does not have need for chop
   #Print this out to have something to watch.
   $width = `identify -format "%w" $pix`; chomp $width;
   $height = `identify -format "%h" $pix`; chomp $height;
   print "Photo size is ", $width, " by ", $height, " pixels.\n";
}

################################################################
#Abbreviated script to only put marker in upper left of pictures

#Load all jpgs into an array.  Remove trailing line feed.
@pix = `ls -1 ./thumbs/*.jpg`;

foreach $pix (@pix) {
   chomp $pix;

   #Annotate the image with a web address.  Upper left always works.
   `convert -fill white -draw 'roundRectangle 1,1 124,12 3,1' $pix $pix`;
   `convert -font Helvetica -fill black -pointsize 12 -draw 'text 3,10 "SMALL_TAG"' $pix $pix`;
   
   #Identify is returning somethin I don't get, so chomp and chop
   #Latest version does not have need for chop
   #Print this out to have something to watch.
   $width = `identify -format "%w" $pix`; chomp $width;
   $height = `identify -format "%h" $pix`; chomp $height;
   print "Photo size is ", $width, " by ", $height, " pixels.\n";
}

Similar Posts