“I am rarely happier than when spending entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.”
- Douglas Adams - From “Last Chance to See”
In recent years I’ve used Google Photos exclusively to manage my photos. It integrates nicely with android, has some great ML features built in, and hits the perfect price point of ‘free’. One feature I really enjoy is the timeline, being able to quickly scrub to a specific point in time is invaluable.
The problem..
So recently when I had a need to scan a number of photos, taken from a time when Kodak and photo labs in shoping malls still existed. One thing I absolutely wanted was a technique to add a date and a comment to every image that I scanned. All prior experience with scanners placed them firmly in 2nd place, right behind printers, for the award Most tempermental PC peripheral. Especially when trying to utilise the bundled software they are provided with, complete with vendor bloatware.
The solution..
Given Python is my weapon of choice at the moment I thought I could build a better scanning hammer. I had a few requirements:
- Command line driven
- Could scan in portrait or landscape mode
- Metadata to be embdeded in images
- Metadata to be input whilst scan was in progress
- Automatic edge detection & cropping
Relatively trivial requirements in my oppinion. The focus was on building something quickly, that would help me optimise my workflow by allowing user input whilst the scanner acquired an image.
pytwain library
One of the best parts of python is the community and available libraries. Mikhail Denisenko has done a lot of the heavy lifting with the pytwain library. Within a few hours I had understood the demos, function calls and processes sufficiently to get a scanner to acquire an image.
Ok great… but the Acquire
call blocks the application. So, the next step was to try and run it in a seperate process. That kinda worked, it would get to acquire but then passing the image handle back to the main process caused process violations. So then I tried to process it in a seperate thread but scanning was still unreliable and handling he image in memory was not terribly clear. The library would sometimes make sense, and at other times was unclear, demo classes made sense but didnt meet my needs. This is before working out how to do edge detection, image manipulation and how to include the metadata.
FAIL
In the end after two days of experimenting and trying to get a multi-threaded scanning utility off the ground my deadline was looming closer and I still had no reliable method of scanning and inputting data so I could work efficiently. So I begrudgingly opened the vendor utility… which had an automatic mode…. that worked perfectly straight out of the box!
Well how about that, two days ‘wasted’ and the vendors system works out of the box. I also found out that it was taking me longer to pull a photo out of the album that it was taking to scan. So my highly optimised process would never have worked been practical as I wouldn’t have had the time to scan and input the data in parrallel whilst maintaining an >80% utilisation of the scanner.
lessons learnt
This whole process was a great refresher in trying a standard process first, before thinking you can invent a better solution. I am also proud that I only spent a few days on a small hobby project that helped to sharpen my skills in external libraries and gave me a bit of exposure to tkinter, a graphical interface for python that I had not come across before.