Category: Utility Scripts
Author/Contact Info Vortacist
Description: This is my first major perlscript (with help from Falkkin)--it scales down the size of images in a specified directory and all of its subdirectories. This is not a compression algorithm--it simply resizes the images based on command-line options. The user may specify size (as "xx%" or a number of pixels), starting directory, and which types of image files to resize. The user is required to specify a size; if none is given, the online help message is printed. Please see this message for more info.

I tend to do a lot of image-resizing for CD-ROM scrapbooks and thumbnails and thought other people might find this script useful for similar tasks.

I would appreciate any suggestions on how to make this script more efficient, and I'd also like to know if the help text is clear enough. Thanks!

Update: Changed code as per merlyn's suggestion below, with one slight difference (see my reply).

#!/usr/bin/perl -w
use strict;
use Image::Magick;
use File::Find;
use Getopt::Long;

# Declares defaults
my($size, $dir, $exts, $is_percent, $help) = 
    ("foo", './', "bmp gif jpg jpeg mng pcd pcx png tga tiff xpm", 0, 

# Changes defaults if specified on command line
GetOptions ('size=s' => \$size, 'directory=s' => \$dir,
        'extensions=s' => \$exts, 'help' => \$help);

# Gives help if indicated
help() if $help || $size eq "foo";

# Creates a hash of valid image extensions
my(@exts) = split(" ", $exts);
foreach (@exts) {
    $_ = lc;
    $exts{$_} = 1;

# Formats the $size as the max dimension for the shrink()
# subroutine later, unless it was given as a percentage.
$size = "${size}x$size" unless $size =~ /%$/;

# Recurses, starting from within the current directory, 
# and shrinks every valid pic it can find
find (\&get_img, $dir);

# Displays help
sub help {
  print <<DONE;

Usage: -s <SIZE> [OPTIONS]
Scales down image files in a directory and all of its subdirectories.

Required parameter is:
-s, --size        May be given as a percentage or as a number of pixel
                  If a percentage is given, the image will be scaled t
                  that percentage. If a number is given, the image wil
+l be
                  scaled so that its largest dimension (height or widt
                  is not greater than the given number in pixels.

Valid options are:
-d, --directory   Directory to begin looking for files in.  Defaults t
+o: ./
-e, --extensions  Only shrink files that end with the given extensions
                  The list of extensions should be quoted, each extens
                  separated by a space.  Valid extensions are all thos
+e file 
                  types supported by PerlMagick.  
                  Defaults to: "bmp gif jpg jpeg mng pcd pcx png tga t
+iff xpm"
-h, --help        Display this help message.

Examples: -d ~/pics -s 400 -e "jpg gif"  
Shrinks all .jpg and .gif files in the ~/pics directory and its subdir
so that no image has a height or width greater than 400 pixels. -s 40% -e "bmp"
Shrinks all .bmp files in the current directory and its subdirectories
+ to 40% 
of their original size.


# If the current item is a file of a valid extension, shrinks it
sub get_img() {
    if (-f) {
    my($ext) = $_;
    $ext =~ s/.*\.(.+)/$1/;
    shrink($_) if $exts{$ext};

# Loads the given image and shrinks it to be within the given size or 
sub shrink() {
    my($name) = shift;
    my($img) = new Image::Magick;
    print "I got to $name!\n";
    print $size;
    $img->Resize('geometry' => $size);