From 5f4a8ce7b3a0e0734963a9425bde977ed35e57e0 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Wed, 24 Oct 2012 11:34:36 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + batch-resize | 35 +++++++++++++++++++++++++ fix-pdf | 60 +++++++++++++++++++++++++++++++++++++++++++ scan-book | 27 +++++++++++++++++++ scan-page | 25 ++++++++++++++++++ scantools/__init__.py | 52 +++++++++++++++++++++++++++++++++++++ 6 files changed, 200 insertions(+) create mode 100644 .gitignore create mode 100755 batch-resize create mode 100755 fix-pdf create mode 100755 scan-book create mode 100755 scan-page create mode 100644 scantools/__init__.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/batch-resize b/batch-resize new file mode 100755 index 0000000..a21a302 --- /dev/null +++ b/batch-resize @@ -0,0 +1,35 @@ +#!/usr/bin/python + +import os, argparse, subprocess + +parser = argparse.ArgumentParser(description='Batch-resizes images.') + +parser.add_argument('images', metavar='IMAGE', type=str, nargs='+', + help='images to resize') + +parser.add_argument('-s', dest='size', action='store', default="40%", + help='size specification to resize to (ImageMagick convert syntax)') + +parser.add_argument('-t', dest='type', action='store', default="tif", + help='filetype to convert to (defaults to TIFF)') + +args = parser.parse_args() +options = vars(args) + +for image in options['images']: + base_name = os.path.splitext(os.path.basename(image))[0] + base_path = os.path.dirname(image) + target_path = "%s/out" % base_path + target_file = "%s/%s.%s" % (target_path, base_name, options['type']) + + try: + os.makedirs(target_path) + except: + pass + + result = subprocess.call(["convert", image, "-resize", options['size'], target_file]) + + if result == 0: + print "Successfully completed '%s' => '%s'" % (image, target_file) + else: + print "Failed conversion for '%s' with error code %d." % (image, result) diff --git a/fix-pdf b/fix-pdf new file mode 100755 index 0000000..70210bc --- /dev/null +++ b/fix-pdf @@ -0,0 +1,60 @@ +#!/usr/bin/python + +import sys, os, argparse + +parser = argparse.ArgumentParser(description='Fixes PDFs that are output by tiff2pdf, to get rid of the pink and green color overlay issue.') + +parser.add_argument('files', metavar='FILE', type=str, nargs='+', + help='files to fix') + +args = parser.parse_args() +options = vars(args) + +def chunked_replace(original_file, target_file, chunk_size, find, replace): + original = open(original_file, "rb") + target = open(target_file, "wb") + position = 0 + + while True: + # Read a normally sized chunk. + data = str(original.read(chunk_size)) + + # Replace all data immediately available in this read. + new_data = data.replace(find, replace) + + # Check for partial matches. We will loop this to deal with false positives when the partial match + # turned out to be random, but another partial match follows immediately afterwards the original + # read. + while True: + found = False + + # We will go from a large substring to a small substring to avoid false positives. + # If we went the other way around, repetitive patterns in the substring might cause havoc. + for length in reversed(xrange(1, len(find))): + if new_data.endswith(find[:length]): + # Partial match found. + missing_bytes = len(match_string) - length + new_data += str(original_file.read(missing_bytes)) + new_data = new_data.replace(find, replace) + found = True + + if found == False: + # No more partial matches to deal with here. + break + + target.write(new_data) + + if data == "": + break + else: + position += chunk_size + + original.close() + target.close() + +for item in options['files']: + base_name, extension = os.path.splitext(os.path.basename(item)) + base_path = os.path.dirname(item) + target_file = "%s/%s_fixed.%s" % (base_path, base_name, extension) + + chunked_replace(item, target_file, 512 * 1024, b"ColorTransform 0", b"ColorTransform 1") diff --git a/scan-book b/scan-book new file mode 100755 index 0000000..bae4dd5 --- /dev/null +++ b/scan-book @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import sane, os +import scantools + +scantools.init() + +project_name = raw_input("Project name? ") + +if project_name == "": + print "No valid project name given!" + exit(1) + +try: + os.makedirs(project_name) +except OSError, e: + print "The given project already exists!" + exit(1) + +raw_input("Press enter to start scanning...") + +i = 1 + +while True: + scantools.scan(project_name, i) + raw_input("[+] Page %d finished, press enter to continue with next page..." % i) + i += 1 diff --git a/scan-page b/scan-page new file mode 100755 index 0000000..7dd5c54 --- /dev/null +++ b/scan-page @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import sane, os +import scantools + +scantools.init() + +project_name = raw_input("[?] Project name? ") + +if project_name == "": + print "No valid project name given!" + exit(1) + +try: + os.makedirs(project_name) +except OSError, e: + print "WARNING: Project exists!" + +num = int(raw_input("[?] What is the number of the first scan? ")) +raw_input("Press enter to start scanning...") + +while True: + scantools.scan(project_name, num) + num = int(raw_input("[+] Page %d finished. What is the number of the next scan? " % num)) + raw_input("Press enter to start scanning...") diff --git a/scantools/__init__.py b/scantools/__init__.py new file mode 100644 index 0000000..1b76900 --- /dev/null +++ b/scantools/__init__.py @@ -0,0 +1,52 @@ +import sane, os + +scanner = None + +def init(**kwargs): + global scanner + + sane.init() + + devices = {} + i = 0 + + print "Available devices:" + + for device in sane.get_devices(): + devices[i] = device[0] + print "%d. [%s] %s %s" % (i, device[3], device[1], device[2]) + i += 1 + + choice = int(raw_input("[?] What device would you like to use? ")) + + try: + scanner = sane.open(devices[choice]) + except KeyError, e: + print "You did not input a valid device ID." + exit(1) + + resolution = raw_input("[?] Scan resolution (DPI)? [default: 300] ") + if resolution == "": + scanner.resolution = 300 + else: + scanner.resolution = int(resolution) + + + width = raw_input("[?] Width (mm)? [default: 214] ") + if width == "": + scanner.br_x = 214 + else: + scanner.br_x = int(width) + + height = raw_input("[?] Height (mm)? [default: 295] ") + if height == "": + scanner.br_x = 295 + else: + scanner.br_x = int(height) + + scanner.tl_x = 0 + scanner.tl_y = 0 + +def scan(projectname, num, **kwargs): + pil_image = scanner.scan() + pil_image.save("%s/%s.png" % (projectname, "{0:04d}".format(num)))