Hey There!

This little perl script acts as a very simple gallery. Just place any images and this script in a directory and access it through your web server and you'll see the thumbnails and through them you can view the original size of the pictures. You can upload any type of pictures, the script will convert them to jpeg. Developement is still underway.

The code's site.

#!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use File::Type; use File::stat; use Image::Magick; my $DIR = "."; #where to look for the files my $percent = 10; #size of the thumbnails my $author = 'gabri.mate@modernbiztonsag.org'; #page author #convert and create thumbnail sub create_thumbnail { my $file = $_[0]; my $image = Image::Magick->new(); $image->Read("$file"); if ( $_[1] ) { #convert section my $oldfile = $file; my @file = split(/\./,$file); $file = $file[0] . ".jpg"; open(IMAGE, ">$file") || die "Can't open $file!"; $image->Write(file=>\*IMAGE, filename=>$file); close(IMAGE); $image = Image::Magick->new(); $image->Read("$file"); unlink($oldfile) || die "Can't unlink $oldfile!"; } my ($width, $height) = $image->Get('width', 'height'); $width = $width * $percent / 100; $height = $height * $percent / 100; $image->Scale(width=>"$width", height=>"$height"); $image->Write("thumbs/$file"); } #check if source file is updated since last thumbnail creation sub check_mtime { my $file = $_[0]; if ( ! -d "$DIR/thumbs/$file") { return(1); } my $filetime = stat($file)->mtime; my $thumbtime = stat("$DIR/thumbs/$file")->mtime; if ( $filetime > $thumbtime ) { return(1); } else { return(0); } } #check is file is an image and if it has a thumbnail or not sub check_mime_type { my $file = $_[0]; my $ft = File::Type->new(); my $type = $ft->mime_type($file); if ( $type =~ /image/ and $type !~ /jpeg/ ) { &create_thumbnail($f +ile,1); } #if image is not jpeg then convert before creating thumbnai +l elsif ( $type =~ /image\/jpeg/ and &check_mtime($file) ) { &create +_thumbnail($file); } #if image is jpeg and hasn't got a thumbnail, or + thumbnail is out of date compared to the source image, then create o +ne } #look for files in $DIR sub collect_files { if ( ! -d "$DIR/thumbs" ) { mkdir("$DIR/thumbs") || die "Can't cre +ate $DIR/thumbs"; } #create thumbs subdir to pleace thumbnails there +serving as cache opendir(DIR, "$DIR") || die "Can't open $DIR!"; while (defined(my $file = readdir(DIR))) { if ( ! -d $file ) { &check_mime_type($file); } } closedir(DIR); } #collect files, create thumbnails and pass list of images back to cgi +output sub collect_thumbs { &collect_files; my @thumbs; opendir(DIR, "$DIR/thumbs") || die "Can't open $DIR/thumbs!"; while (defined(my $file = readdir(DIR))) { if ( ! -d "$DIR/thumbs/$file" ) { push(@thumbs, $file); } } closedir(DIR); return @thumbs; } #cgi output sub index { print header; print start_html( -title=>'Thumbnail index', -author=>"$author", ); my @thumbs = &collect_thumbs; foreach (@thumbs) { print "<a href='$_' target='_blank'><img src='thumbs/$_'></a>\ +n"; } print end_html(); } &index;

Replies are listed 'Best First'.
Re: Thumbnail autoindex
by jwkrahn (Abbot) on Dec 06, 2008 at 21:30 UTC
    #look for files in $DIR sub collect_files { opendir(DIR, "$DIR"); while (defined(my $file = readdir(DIR))) { if ( ! -d $file ) { &check_mime_type($file); } } closedir(DIR); } #collect files, create thumbnails and pass list of images back to cgi +output sub collect_thumbs { &collect_files; my @thumbs; opendir(DIR, "$DIR/thumbs"); while (defined(my $file = readdir(DIR))) { if ( ! -d $file ) { push(@thumbs, $file); } } closedir(DIR); return @thumbs; }

    readdir gives you a file name from the directory $DIR (or "$DIR/thumbs") but you are not testing the file in that directory ( ! -d $file ), you are testing it in the current directory.   You need to prepend the directory name to the file name to test the correct file.

    You should also always verify that open, opendir and unlink worked correctly.

    See also: What's wrong with always quoting "$vars"?

      Thank you for your advice! It's obvious that i don't have enough experience yet. I'll add the suggested verification.
Re: Thumbnail autoindex
by zentara (Cardinal) on Dec 07, 2008 at 13:59 UTC
    You can improve the efficiency of your script, especially when alot of images are added, by making just 1 ImageMagick object and reusing it. If you undef @$image; you can clear out all the previous data from the IM object and reuse it, which is faster than repeatedly creating a new one.
    #!/usr/bin/perl use warnings; use strict; use Image::Magick; my $image = Image::Magick->new; umask 0022; my @pics= <*.jpg>; #my @pics= <*.jpg *.gif *.png>; #add all your extensions here foreach my $pic (@pics){ my ($picbasename) = $pic =~ /^(.*).jpg$/; my $ok; $ok = $image->Read($pic) and warn ($ok); my $thumb = $picbasename . '-t.jpg'; $image->Scale(geometry => '100x100'); $ok = $image->Write($thumb) and warn ($ok); undef @$image; #needed if $image is created outside loop print "$pic -> $thumb\n"; }

    I'm not really a human, but I play one on earth Remember How Lucky You Are
      Thank you for the advice. I'll modify the code to use 1 ImageMagick object.