bmattock
Veteran
I have a collection of old "Kodakery" magazines from the 1920's that I want to use on a website I'm building. I have a flatbed scanner, the Perl programming language, and an Internet connection. Using these, I can scan the pages, trim them, adjust levels, set Exif metadata in the resulting images, and then upload them to Flickr, all in one step. I am including my Perl code for anyone who wants to do this as well.
Needed:
Perl (Linux, Mac, or Windows. My example is for Linux)
Perl Modules (GraphicsMagick, ExifTool, and FlickrUpload)
The tools are all free, as is Perl. No reason any of this should cost anything.
http://www.graphicsmagick.org/perl.html
http://www.sno.phy.queensu.ca/~phil/exiftool/
http://search.cpan.org/~cpb/Flickr-Upload-1.32/
Flatbed Scanner. I'm using an Epson Perfection 4490. Any flat bed scanner should work. I am also using Vuescan as my scanning software. I am setting DPI at 75 and scanning using the 'magazine' setting. I suppose you could scan it in any format you wished, but I chose the default 75 DPI so that the resulting scans would not take up a lot of disk space.
I scan all the pages of the magazine, laying them flat and scanning two pages at a time:

I do the outside cover and back cover, then do the inside, ending up on the last page and the inside of the back cover. This is only important due to the 'page counting' that my script does to insert the appropriate page number as metadata later. If you do it differently, you'll want to change the counting method as well.
I then used a graphics editing program (The GIMP, but you can use what you like) to determine the number of pixels across the scan is. I divide that in half, because I'll be asking GraphicsMagic to cut the image down the middle. I tried having my scanner scan two images instead of one, but it kept getting confused and hosing up the dividing line between the two pages (I used Vuescan). If you have better luck at that than I did, then you can get rid of the redundant bits of code where I cut the image in half.
I have hard-coded the pixel count for my scans, but you will want to change these for yours. The 'geometry' is width (1580) by height (2200). The +1581 is the offset for page two of each scan (since I'm splitting the initial scan into two images, one for each page).
I have a number of replacement variables that I then set in my code, which tells the Perl script where the scans are located and what they are called. It also contains the information that you want to use for titling the resulting new images, inserting appropriate metadata, and so on. You will want to replace all of that with your own information for whatever you're scanning.
I also make use of the Flickr Upload Perl module to insert the Flickr Tags, which are particularly hard to with the metadata. Supposedly, there is a way to set the images' metadata so that Flickr picks up the 'Keywords' attribute and sets the Flickr Tags appropriately, but I've had nothing but trouble with it. This walks around that problem.
You will also need to apply for your own Flickr API information.
It's free, you can get it here: http://www.flickr.com/services/api/keys/apply/
Naturally, you also need a Flickr account.
That's pretty much it. You end up with something that looks like this:

Click on the image above and you can see how the values have been set in Flickr - all done automatically as a result of this script. I leave the image in the initial state of 'private' which means no one can see them but you, but you can change that yourself in Flickr, or you can put that into your Flickr Upload module argument. The directions for this sort of thing are here:
http://search.cpan.org/~cpb/Flickr-Upload-1.32/flickr_upload
Hope you find it useful. I know it is going to save me a ton of time and effort.
Needed:
Perl (Linux, Mac, or Windows. My example is for Linux)
Perl Modules (GraphicsMagick, ExifTool, and FlickrUpload)
The tools are all free, as is Perl. No reason any of this should cost anything.
http://www.graphicsmagick.org/perl.html
http://www.sno.phy.queensu.ca/~phil/exiftool/
http://search.cpan.org/~cpb/Flickr-Upload-1.32/
Code:
use strict;
use File::Find ();
use File::Copy;
use Time::Local;
use Image::ExifTool qw(:Public);
use Graphics::Magick;
use Flickr::Upload;
Flatbed Scanner. I'm using an Epson Perfection 4490. Any flat bed scanner should work. I am also using Vuescan as my scanning software. I am setting DPI at 75 and scanning using the 'magazine' setting. I suppose you could scan it in any format you wished, but I chose the default 75 DPI so that the resulting scans would not take up a lot of disk space.
I scan all the pages of the magazine, laying them flat and scanning two pages at a time:

I do the outside cover and back cover, then do the inside, ending up on the last page and the inside of the back cover. This is only important due to the 'page counting' that my script does to insert the appropriate page number as metadata later. If you do it differently, you'll want to change the counting method as well.
I then used a graphics editing program (The GIMP, but you can use what you like) to determine the number of pixels across the scan is. I divide that in half, because I'll be asking GraphicsMagic to cut the image down the middle. I tried having my scanner scan two images instead of one, but it kept getting confused and hosing up the dividing line between the two pages (I used Vuescan). If you have better luck at that than I did, then you can get rid of the redundant bits of code where I cut the image in half.
I have hard-coded the pixel count for my scans, but you will want to change these for yours. The 'geometry' is width (1580) by height (2200). The +1581 is the offset for page two of each scan (since I'm splitting the initial scan into two images, one for each page).
Code:
$error = $image->Crop(geometry=>'1580x2200');
$error = $image->Crop(geometry=>'1580x2200+1581');
I have a number of replacement variables that I then set in my code, which tells the Perl script where the scans are located and what they are called. It also contains the information that you want to use for titling the resulting new images, inserting appropriate metadata, and so on. You will want to replace all of that with your own information for whatever you're scanning.
Code:
# To be modified as needed...
my $scandir = "/home/bmattock/Photos/Kodakery/1925";
my $scandate = "Scan-081109-";
my $title = "Kodakery";
my $description = "\'A Magazine for Amateur Photographers\'";
my $cover_date = "December, 1925";
my $expanded_description = "Kodakery was a monthly magazine published by <a href=\"http://www.kodak.com\">Eastman Kodak</a> from September, 1913 through 1932.";
my $year = "1925";
my $month = "12";
my $day = "01";
my $hour = "00";
my $min = "00";
my $sec = "00";
my $Make = "Epson";
my $Model = "Perfection 4490";
my $PageName = "Reflective";
my $Copyright = "Eastman Kodak Company";
# End of to be modified as needed...
I also make use of the Flickr Upload Perl module to insert the Flickr Tags, which are particularly hard to with the metadata. Supposedly, there is a way to set the images' metadata so that Flickr picks up the 'Keywords' attribute and sets the Flickr Tags appropriately, but I've had nothing but trouble with it. This walks around that problem.
Code:
# One more to be modified as needed...
my $tags = "Eastman Kodak, Eastman, Kodak, Kodakery, magazine, historic, photography, amateur, Rochester, New York, $year, $monthname, $Make, $Model";
You will also need to apply for your own Flickr API information.
Code:
my $auth_token = "big long number and letter string";
my $key = "big long number and letter string";
my $secret = "shorter number and letter string";
It's free, you can get it here: http://www.flickr.com/services/api/keys/apply/
Naturally, you also need a Flickr account.
That's pretty much it. You end up with something that looks like this:

Click on the image above and you can see how the values have been set in Flickr - all done automatically as a result of this script. I leave the image in the initial state of 'private' which means no one can see them but you, but you can change that yourself in Flickr, or you can put that into your Flickr Upload module argument. The directions for this sort of thing are here:
http://search.cpan.org/~cpb/Flickr-Upload-1.32/flickr_upload
Hope you find it useful. I know it is going to save me a ton of time and effort.
Code:
#!/usr/bin/perl
use strict;
use File::Find ();
use File::Copy;
use Time::Local;
use Image::ExifTool qw(:Public);
use Graphics::Magick;
use Flickr::Upload;
my $image = Graphics::Magick->new;
my $exifTool = new Image::ExifTool;
my $auth_token = "replace with your own string from Flickr";
my $key = "replace with your own string from Flickr";
my $secret = "replace with your own string from Flickr";
my $flickr_sender = "TRUE";
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
my @files;
my $error;
my $counter = 0;
my $outfile;
# To be modified as needed...
my $scandir = "/home/bmattock/Photos/Kodakery/1925";
my $scandate = "Scan-081109-";
my $title = "Kodakery";
my $description = "\'A Magazine for Amateur Photographers\'";
my $cover_date = "December, 1925";
my $expanded_description = "Kodakery was a monthly magazine published by <a href=\"http://www.kodak.com\">Eastman Kodak</a> from September, 1913 through 1932.";
my $year = "1925";
my $month = "12";
my $day = "01";
my $hour = "00";
my $min = "00";
my $sec = "00";
my $Make = "Epson";
my $Model = "Perfection 4490";
my $PageName = "Reflective";
my $Copyright = "Eastman Kodak Company";
# End of to be modified as needed...
my $monthname;
my $page_number;
my $mtime;
print "Month is: $month\n";
if ($month eq "01"){$monthname = "January";}
elsif ($month eq "02"){$monthname = "February";}
elsif ($month eq "03"){$monthname = "March";}
elsif ($month eq "04"){$monthname = "April";}
elsif ($month eq "05"){$monthname = "May";}
elsif ($month eq "06"){$monthname = "June";}
elsif ($month eq "07"){$monthname = "July";}
elsif ($month eq "08"){$monthname = "August";}
elsif ($month eq "09"){$monthname = "September";}
elsif ($month eq "10"){$monthname = "October";}
elsif ($month eq "11"){$monthname = "November";}
elsif ($month eq "12"){$monthname = "December";}
else {$monthname = "Uknown";}
# One more to be modified as needed...
my $tags = "Eastman Kodak, Eastman, Kodak, Kodakery, magazine, historic, photography, amateur, Rochester, New York, $year, $monthname, $Make, $Model";
sub wanted;
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, $scandir);
@files = sort(@files);
foreach(@files)
{
if($counter == 0){$page_number = "Back Cover";}
elsif($counter == 1){$page_number = "Front Cover";}
elsif($counter == 2){$page_number = "Inside Cover";}
else{$page_number = ($counter-2);}
$image = Graphics::Magick->new;
print "$_\n";
$error = $image->Read($_);
warn "$error" if "$error";
$error = $image->Crop(geometry=>'1580x2200');
warn "$error" if "$error";
$error = $image->Normalize();
warn "$error" if "$error";
$outfile=$scandir."/".$title."_".$monthname."_".$year."_".$counter.".jpg";
$error = $image->Write("$outfile");
warn "$error" if "$error";
$exifTool->ExtractInfo($outfile);
$error = $exifTool->SetNewValue("DateTimeOriginal", "$year:$month:$day:$hour:$min:$sec");
$error = $exifTool->SetNewValue("CreateDate", "$year:$month:$day:$hour:$min:$sec");
$error = $exifTool->SetNewValue("Title", "$title - $cover_date");
$error = $exifTool->SetNewValue("Description", "$description\n\n$expanded_description\n\nPage: $page_number");
$error = $exifTool->SetNewValue("ImageDescription", "$description\n\n$expanded_description\n\nPage: $page_number");
$error = $exifTool->SetNewValue("Make", "$Make");
$error = $exifTool->SetNewValue("Model", "$Model");
$error = $exifTool->SetNewValue("PageName", "$PageName");
$error = $exifTool->SetNewValue("Copyright", "$Copyright");
if ($error)
{
$error = $exifTool->WriteInfo($outfile);
print "Update failed", $exifTool->GetValue('Error'), "\n" if ! $error;
}
$mtime = timelocal($sec,$min,$hour,$day,$month-1,$year);
utime $mtime, $mtime, $outfile;
if($flickr_sender eq "TRUE")
{
&send_to_flickr();
}
$counter++;
if($counter == 0){$page_number = "Back Cover";}
elsif($counter == 1){$page_number = "Front Cover";}
elsif($counter == 2){$page_number = "Inside Cover";}
else{$page_number = ($counter-2);}
$image = Graphics::Magick->new;
print "$_\n";
$error = $image->Read($_);
warn "$error" if "$error";
$error = $image->Crop(geometry=>'1580x2200+1581');
warn "$error" if "$error";
$error = $image->Normalize();
warn "$error" if "$error";
$outfile=$scandir."/".$title."_".$monthname."_".$year."._".$counter.".jpg";
$error = $image->Write("$outfile");
warn "$error" if "$error";
$exifTool->ExtractInfo($outfile);
$error = $exifTool->SetNewValue("DateTimeOriginal", "$year:$month:$day:$hour:$min:$sec");
$error = $exifTool->SetNewValue("CreateDate", "$year:$month:$day:$hour:$min:$sec");
$error = $exifTool->SetNewValue("Title", "$title - $cover_date");
$error = $exifTool->SetNewValue("Description", "$description\n\n$expanded_description\n\nPage: $page_number");
$error = $exifTool->SetNewValue("ImageDescription", "$description\n\n$expanded_description\n\nPage: $page_number");
$error = $exifTool->SetNewValue("Make", "$Make");
$error = $exifTool->SetNewValue("Model", "$Model");
$error = $exifTool->SetNewValue("PageName", "$PageName");
$error = $exifTool->SetNewValue("Copyright", "$Copyright");
if ($error)
{
$error = $exifTool->WriteInfo($outfile);
print "Update failed", $exifTool->GetValue('Error'), "\n" if ! $error;
}
$mtime = timelocal($sec,$min,$hour,$day,$month-1,$year);
utime $mtime, $mtime, $outfile;
$counter++;
if($flickr_sender eq "TRUE")
{
&send_to_flickr();
}
}
exit;
sub wanted {
/^$scandate.*\.jpg\z/s &&
push(@files, $name);
}
sub send_to_flickr {
my $ua = Flickr::Upload->new(
{
'key' => $key,
'secret' => $secret
});
$ua->upload(
'photo' => $outfile,
'auth_token' => $auth_token,
'tags' => $tags,
'is_public' => 0,
'is_friend' => 0,
'is_family' => 0
) or die "Failed to upload $outfile";
}