#!/usr/bin/perl -w
#by Torben Menke 2008-02-09
#http://www.entorb.net
# replace the prefix of many imaged at once: img1234->tm1234
# reduce scaling of many images and set the jpg-compress-rate


use strict;
use warnings;
use Image::Magick;
#use Data::Dumper;

my @filelist = ( @ARGV ? @ARGV : <*>); # if no files given as parameters, use cwd
@filelist = grep {m/\.jpe?g$/i and -f} @filelist ;
my $countTotal = 1+ $#filelist;

my $prefix='';
my $maxsize = 2048;
my $jpg_compress_quality = 85;
my $input;
my ($renamecount, $renameerror, $resizecount, $resizeerror) = (0,0,0,0);

print "\nWorking on $countTotal images\n";

print "Enter new file prefix [default: no change]: ";
chomp ($input = <STDIN>);
$input =~ s/^\s*([^\s]*)\s*/$1/; #cleaning white spaces
$input ne ''
and $prefix = $input;

print "\nEnter max image size in pixel in one direction (0 = keep size) [default: $maxsize]: ";
chomp ($input = <STDIN>);
$input =~ s/^\s*([^\s]*)\s*/$1/; #cleaning white spaces
if ($input ne ''){ # keep default if $input == ''
if ($input =~ /^[0-9]+$/ and (($input+=0)>=0) and $input <=10000 and $input >=0) {
$maxsize = $input;
}
else {
print "\n Bad input, used default!";
}
}
print "\nEnter jpg quality (100 = highest) (0 = keep quality) [default: $jpg_compress_quality]: ";
chomp ($input = <STDIN>);
$input =~ s/^\s*([^\s]*)\s*/$1/; #cleaning white spaces
if ($input ne ''){ # keep default if $input == ''
if ($input =~ /^[0-9]+$/ and (($input+=0)>=0) and $input <= 100 and $input >= 0) {
$jpg_compress_quality = $input;
}
else {
print "\n Bad input, used default!";
}
}

print "prefix = $prefix size = $maxsize q = $jpg_compress_quality\n";

my $count = 0;
foreach my $file (@filelist) {
$count ++;
my $str = '';
$str .= ' ' if ($count < 100);
$str .= ' ' if ($count < 10);
$str .= "$count/$countTotal";

print "$str $file ";
# check and ensure write access
if (not -w $file) {
if (not chmod 0644, $file) {
print "file is write protected! -SKIPPING\n";
next;
}
}

# renaming
if ($prefix ne ''){
my ($new, $old) = ($file,$file);
$new =~ s/(^|[\\\/])[^\/\\\d]+([\d]+)\.(jpe?g)$/\L$1\E$prefix\L$2\.$3\E/i; #\L = lowercase till \E
# check if filename is like 100_1234.jpg
if ( $new eq $old and $old=~m/(^|[\\\/])(\d{3,5}_)(\d{3,8}\.jpe?g)$/i ) {
$new =~ s/(^|[\\\/])(\d{3,5}_)(\d{3,8}\.jpe?g)$/$1$prefix$3/i;
}
if (($old ne $new) and not (-f $new)){
if (rename $old,$new){
print "-> $new ";
$renamecount++;
$file = $new;
} else {
print "ERROR: can not rename $old -> $new\n";
$renameerror++;
}
} else {
print "NOT renamed\n";
$renameerror++;
}
($new,$old) = (undef,undef);
}


# rescaling
if ($jpg_compress_quality>0 or $maxsize>0) {
my $image = new Image::Magick;
my $result=$image->Read($file);
die $result if $result;
my ($x, $y) = $image -> Get('width','height');
if ($maxsize>$x and $maxsize>$y) {
print "file is <= than ".$maxsize."px SKIPPING\n";
next;
}
my $ratio = $x/$y;

# change compress-level
$jpg_compress_quality > 0
and $image->Set(quality=>$jpg_compress_quality);

# change scaling
if ($maxsize>0) {
if ($x>=$y) {
$image -> Scale(width => $maxsize, height => $maxsize/$ratio);
# SLOWER $image -> Resize(width =>$maxsize, height => $maxsize/$ratio);
} else {
$image -> Scale(height => $maxsize, width => $maxsize*$ratio);
}
}
$image -> Write($file);
$resizecount++;
# TODO does not work:
# if ($image -> Write($file)){
# $resizecount++;
# } else {
# $resizeerror++;
# }
}

# Old Version: Using ImageMagick via Shell
# ===========
# if ($jpg_compress_quality>0 or $maxsize>0) {
# -w $file or chmod 0644, $file;
# my $str = "mogrify";
# ($jpg_compress_quality > 0) and ($str .= " -quality $jpg_compress_quality");
# ($maxsize > 0) and ($str .= " -size ".$maxsize."x".$maxsize." -resize ".$maxsize."x".$maxsize."\\\>");
# $str .= " $file"; #filename
# system ($str);
# }
print " -done-\n";
}
print "Job done!!!\n";
if ($prefix ne '') {
print "$renamecount files renamed. ";
print "$renameerror files not renamed." if $renameerror;
print "\n";
}
if ($jpg_compress_quality >0 or $maxsize>0) {
print "$resizecount files resized. ";
print "$resizeerror files not resized." if $resizeerror;
print "\n";
}

Hope you found what you where looking for. Feel free to drop me a line
Torben