Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I asked about this a couple of weeks ago-- and although the answers were correct they didn't end producing a solution.

My question:
I need a script that will automatically make a thumbnail image.

The answers I got last time were to use Image::Magick or GD module. In both cases I can't install the modules in my directories because I don't have root access. They require some additional compiling in C. My host company is very slow to help me (after three weeks of bugging them everyday they haven't helped me).

So now my questions is:
Does anyone have a simple script that doesn't require any modules (other than the standard ones) that can produce a thumbnail image? Quality is not that important (within reason) I just need thumbnail images made.

Thanks for any insight
Ashley
ashleyscottmeyers@yahoo.com

Replies are listed 'Best First'.
Re: thumbnails
by jlongino (Parson) on Feb 01, 2002 at 00:55 UTC
    I know that this solution may not be optimal, but with a little elbow grease you should be able to use this method. You can install Active State Perl on your personal computer (assuming windows here), use ppm to install Image::Magick, ftp/scp (whatever) the original pics to your pc (preferably in a directory of their own), modify and run the code I've included below, ftp the resulting thumbnails to the target website. This procedure does not require having a C compiler.

    This code was based on code that ar0n submitted. I've added some error checking and other stuff:

    use strict; use Image::Magick; # Allowable image suffixes my %IMsuffixes = ( jpg => 1, bmp => 1, gif => 1, jpeg => 1, png => 1, tiff => 1, tif => 1, wpg => 1 ); my $max_dim = 125; my $path = 'C:/My Files/My pictures/Pets'; my @images = glob "'$path/*'"; print "Path: '$path'\n"; foreach (@images) { s!.*/!!; # we won't process a file that is already prefixed with 'tn.' next if lc substr($_, 0, 3) eq 'tn.'; my $suf = $_; $suf =~ s/.*\.//; if (exists $IMsuffixes{$suf}) { # The resulting thumbnail is named "tn." + $original_filename ThumbNail($path, $_, "tn.", $max_dim); } else { print "INVALID suffix: '.$suf', file: '$_' Skipping . . .\n"; } } sub ThumbNail { my ($path, $file, $prefix, $max_dim) = @_; if (! ($path && $file && $prefix && $max_dim)) { print "ERROR - Invalid Parameter to sub 'ThumbNail': \n", " path => '$path\n'", " file => '$file'\n", " prefix => '$prefix'\n", " max_dim => '$max_dim'\n\n"; exit; } my $img = new Image::Magick; my $imerrmsg = $img->Read("$path/$file"); Process_IM_Error($imerrmsg) if $imerrmsg; my ($width, $height) = $img->Get("width", "height"); if ($width * $height == 0) { print "ERROR - Image: '$path/$file' dimensions must be nonzero: +\n", " width => '$width'\n", " height => '$height'\n\n"; exit; } my ($new_height, $new_width); if ($width > $height) { $new_width = $max_dim; $new_height = int($height * $new_width / $width); } else { $new_height = $max_dim; $new_width = int($width * $new_height / $height); } $imerrmsg = $img->Resize( width => $new_width, height => $new_height, blur => 1 ); Process_IM_Error($imerrmsg) if $imerrmsg; $img->Write("$path/$prefix$file"); print pack("A48", "$prefix$file"), " W => ", pack("A3", $new_width), " H => ", pack("A3", $new_height), "\n"; } sub Process_IM_Error { my $errmsg = shift; print "Made it to Process_IM_Error sub\n"; print shift, "\n"; if ("$errmsg") { $errmsg =~ /(\d+)/; exit if ($1 >= 400); } }

    --Jim

Re: thumbnails
by Sinister (Friar) on Feb 01, 2002 at 00:09 UTC
    If you are running on a UN*X box you might want to try to use convert - it can do everything the ImageMagick module can (and more) and is just run on the shell - heck, you can even build a shell script for this. If the thumbnails need to be all of the same size, thinks would look like this:
    #!/bin/zsh a=`find $1 -type f | grep -E 'gif|jpg'` for img in $a do echo "found : $img" echo $img | perl -e 'while (<>) { s/(\w+)\.(\w+)$/$1\.thumb\.$2/; pr +int $_ }'\ | while read thumb do convert -scale 50x50 $img $thumb done done
    tested and works...

    Sinister greetings.
    "With tying hashes you can do everything God and Larry have forbidden" -- Johan Vromans - YAPC::Europe 2001
    perldoc -q $_
      Could you please specify the version(s) of Unix? It apparently isn't a Solaris command. Nor does it appear to be on FreeBSD.

      Update: D'oh! I should know better than to try to post a quickie from work. See my post below.

      --Jim

        To avoid some confusion, convert is just a command-line front-end to the ImageMagick core. Image::Magick is the perl front-end to the same basic libraries. If installing the core ImageMagick stuff is out, so is convert.

        -Blake

(cLive ;-) Re: thumbnails
by cLive ;-) (Prior) on Feb 01, 2002 at 07:43 UTC
    No, but you might want to invest in an image server account.

    I've just integrated it into our shopping cart and must say that I'm quite impressed with the features they offer.

    cLive ;-)

    ps - I have not bothered to read up on the pricing though, just my .02 from reading the tec docs.

Re: thumbnails
by shotgunefx (Parson) on Feb 01, 2002 at 03:42 UTC
    Do you have any say in the images? (format, etc)

    If so, you could probably roll your own fast routines with Inline:C or XS. (Not that it couldn't be pure Perl.)

    -Lee

    "To be civilized is to deny one's nature."
Re: thumbnails
by FoxtrotUniform (Prior) on Feb 01, 2002 at 20:21 UTC

    Well, if you're planning on doing this with vanilla Perl, you'll definitely want to get the images into a format that's pleasant to work with, which is Targa. (Head on over to http://wotsit.org to get the Targa specs; you'll probably want RGB, non-compressed.) So what you'll want to do is:

    1. Get the image into Targa format
    2. Strip the header, getting useful information like image dimensions out of it. Use unpack for this, I think.
    3. Read the image data.
    4. Take the weighted average of MxN pixel blocks, where M is (image_x/thumb_x) and N is (image_y/thumb_y), to get each of the thumbnail pixels. You'll probably have to do a bit of gamma correction to get the colours right, but with small images you might not have to. You can get as tricky as you want with this step, but DON'T just pick a random pixel (or the top-left pixel) in each sample rect, unless you don't mind the thumbnail looking like crap. Read up on supersampling for more info.
    5. Write out a smaller Targa with the thumbnail data.

    Targas are nice and easy to work with. By the way, I've run across some TGA headers generated by ImageMagick that were missing some (admittedly nonessential) data, so be careful with that.

    --
    :wq
Re: thumbnails
by thraxil (Prior) on Feb 01, 2002 at 23:45 UTC

    do you have shell access? you can compile the imagemagick libs without root access by using ./configure --prefix=/some/directory/you/can/write/to. then you can compile Perl::Magick referencing those libs.

    anders pearson

Re: thumbnails
by Anonymous Monk on Feb 01, 2002 at 02:01 UTC
    One more point of clarification.. the thumbnails are going to be made on an ongoning basis, a user will sign up, upload their picture, and then I need to automatically make a thumbnail at the same time. So installing Image::Magick locally won't really help me, it'll convert the images I have so far, but not all the new ones, which are uploaded by users to my site.

    Thanks again
    Ashley