#!/usr/bin/perl -w # Copyright (C) 2009 Glen Pitt-Pladdy # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # # Put files to process as command line arguments use Image::Magick; #$debug = 1; # these parameters are suitable for files that are being printed at 720DPI # at 360DPI then halve the radius': eg. $UNSHARP = '3x1+1.5+0'; $BLUR = 2; # or scale them accordingly for your resolution (yes - I could have done # this automatically too!)OB $UNSHARP = '6x2+1.5+0'; $NOSHARPRATIO = 0.5; # amount of std dev above mean below which unsharpened $FULLSHARPRATIO = 1.0; # amount of std dev above mean above which full sharp $MINSHARP = 0.3; # minimum amount of sharpening $BLUR = 4; # amount to blur edge selection by for $file (@ARGV) { $base = $file; $base =~ s/\.\w+$//; print "processing $file\n"; # read in $image=Image::Magick->new; $image->Read ( $file ); # unsharp $unsharp = $image->Clone; $unsharp->UnsharpMask ( geometry=>$UNSHARP ); # write unsharp if ( $debug ) { $unsharp->Write ( $base.'-usm.tif' ); } # get difference $mask = $unsharp->Clone; $mask->Composite ( compose=>'Difference', image=>$image ); # smooth $mask->Blur ( geometry=>"0x$BLUR" ); # loose colour $mask->Modulate ( saturation=>0 ); # sort levels $mask->Normalize; # analyse @histogram = $mask->Histogram; $mean = 0; $count = 0; undef @hist; while (@histogram) { @colour = splice @histogram, 0, 5; if ( $colour[0] > 0 and $colour[0] < 0xffff ) { # work out mean $mean += $colour[0] * ( $colour[4] ** 2 ); $count += $colour[4] ** 2; } $hist[$colour[0]] = $colour[4]; } $mean /= $count; # find the stddev $stddev = 0; $count = 0; for ( $i = 1; $i < 0xffff; ++$i ) { if ( $hist[$i] ) { $stddev += ( ( $mean - $i ) ** 2 ) * $hist[$i]; $count += $hist[$i]; } } $stddev = ( $stddev / $count ) ** 0.5; # work out target levels $blackpoint = $mean + ( $stddev * $NOSHARPRATIO ); $whitepoint = $mean + ( $stddev * $FULLSHARPRATIO ); # apply levels $mask->Level ( 'black-point'=>$blackpoint, 'white-point'=>$whitepoint ); # apply shifts (minimum sharpness) $mask->Negate; $mask->Modulate ( brightness=>int(100*(1-$MINSHARP)) ); $mask->Negate; # write if ( $debug ) { $mask->Write ( $base.'-mask.tif' ); } # apply to final $image->Composite ( composite=>'src-over', image=>$unsharp, mask=>$mask ); # write $image->Set ( depth=>8, compression=>'Zip' ); # keep it smallOA $image->Write ( $base.'-out.tif' ); }