Scan and automatically crop many images with SANE and ImageMagick
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use POSIX ":sys_wait_h"; | |
STDOUT->flush(); | |
use File::Which qw( which ); | |
foreach ( qw| convert scanimage | ) { | |
unless (which("$_")) { | |
die "Missing dependency: $_\n"; | |
} | |
} | |
unless (scalar @ARGV) { | |
die "Requires project name as argumunt\n"; | |
} | |
my $base; | |
my $resume = 0; | |
foreach (@ARGV) { | |
if ( $_ eq '-R' && !$resume ) { | |
$resume = 1; | |
} elsif (!defined($base)) { | |
$base = $_; | |
} else { | |
die "Invalid or extraneous argument $_\n"; | |
} | |
} | |
if ( -d $base && !$resume ) { | |
die "Directory $base already exists. Use -R to resume an existing project.\n"; | |
} else { | |
mkdir $base; | |
} | |
my @crops; | |
my $pid = 0; | |
my $ctr = 0; | |
if ($resume) { | |
while (-e sprintf("$base/$base-%03d.jpeg",$ctr)) { | |
$ctr++; | |
} | |
print "Resuming at $ctr\n."; | |
} | |
while ($ctr < 1000) { | |
my $file = sprintf("$base-%03d.jpeg",$ctr); | |
# Short delay just so that replace instruction follows after fork output | |
sleep 1; | |
print "Replace image then press Enter ('q' to finish) "; | |
my $c = getc; | |
if ($c eq 'q') { | |
last; | |
} | |
print "\rScanning to $base/$file\n"; | |
#`cp carole-000.jpeg $file`; | |
`scanimage --format jpeg --output $base/$file --progress --mode Color --resolution 600`; | |
pipe(FROM_CHILD, TO_PARENT); | |
my $newpid = fork; | |
# Store all conversion pids | |
if ($newpid) { | |
close(TO_PARENT); | |
push @crops, $newpid; | |
$pid = $newpid; | |
# Convert image on another thread while scanning next image | |
} else { | |
close(FROM_CHILD); | |
# FAIL: cannot wait on sibling process, only child | |
# If there's already a conversion thread going wait for it to finish. | |
#if (scalar(@crops)) { | |
#my $wait = pop @crops; | |
#print "$$ waiting on $wait\n"; | |
#waitpid($wait, 0); | |
#} | |
my ($wh, $t) = split(' ',`convert $base/$file -blur 0x30 -fuzz 5% -trim info: | cut -d ' ' -f 3-4`); | |
chomp $t; | |
my ($w, $h) = split('x',$wh); | |
my ($null, $x, $y) = split('\+',$t); | |
$| = 1; | |
print TO_PARENT "Cropping $base/$file in background width=$w height=$h x=$x y=$y \n"; | |
$w -= 48; | |
$h -= 48; | |
`convert $base/$file -crop ${w}x${h}+${x}+${y} +repage $base/cropped-$file`; | |
exit; | |
} | |
$ctr++; | |
} | |
print "Finishing auto-cropping...\n"; | |
for (my $i = 0; $i < scalar(@crops); $i++) { | |
waitpid($crops[$i], 0); | |
print "Finished " . ($i+1) . " of " . scalar(@crops) . " (${crops[$i]})\n"; | |
} | |
print "Done\n"; | |
exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment