# HG changeset patch # User Paul Boddie # Date 1444162972 -7200 # Node ID 6adea19bfcc290ccdfeed2d4a5c8182b31ab0201 # Parent 1036d8b98d851872a7c994c9b50e20621a36054f Added options for verifying the number of colours per row, half-resolution previews, not producing an output image. Fixed EXIF object usage (which used a nasty global variable). Simplified the get_colours function signature. diff -r 1036d8b98d85 -r 6adea19bfcc2 optimiser.py --- a/optimiser.py Tue Oct 06 17:33:36 2015 +0200 +++ b/optimiser.py Tue Oct 06 22:22:52 2015 +0200 @@ -116,7 +116,8 @@ def amplify_value(x, exp): return int(pow(x / 255.0, exp) * 255.0) -def get_colours(im, width, y): +def get_colours(im, y): + width, height = im.size c = {} for x in range(0, width): rgb = im.getpixel((x, y)) @@ -151,8 +152,8 @@ im.putpixel((x, y), get_value(rgb)) im.save("rgb%02d%02d%02d.png" % rgb) -def rotate_and_scale(im, width, height, rotate): - if rotate or x and x["Image Orientation"].values == [6L]: +def rotate_and_scale(exif, im, width, height, rotate): + if rotate or exif and exif["Image Orientation"].values == [6L]: im = im.rotate(270) w, h = im.size @@ -163,6 +164,16 @@ return im.resize((width, height)) +def count_colours(im, colours): + width, height = im.size + for y in range(0, height): + l = set() + for x in range(0, width): + l.add(im.getpixel((x, y))) + if len(l) > colours: + return (y, l) + return None + if __name__ == "__main__": if "--test" in sys.argv: test() @@ -178,57 +189,78 @@ basename, ext = splitext(output_filename) preview_filename = "".join([basename + "_preview", ext]) - rotate = "-r" in sys.argv[3:] - saturate = sys.argv[3:].count("-s") - desaturate = sys.argv[3:].count("-d") - darken = sys.argv[3:].count("-D") - brighten = sys.argv[3:].count("-B") - preview = "-p" in sys.argv[3:] - square = "-2" in sys.argv[3:] and square or (lambda x: x) + options = sys.argv[3:] - x = EXIF.process_file(open(input_filename)) - im = PIL.Image.open(input_filename).convert("RGB") - im = rotate_and_scale(im, width, height, rotate) + rotate = "-r" in options + saturate = options.count("-s") + desaturate = options.count("-d") + darken = options.count("-D") + brighten = options.count("-B") + square = "-2" in options and square or (lambda x: x) + preview = "-p" in options + half_resolution_preview = "-h" in options + verify = "-v" in options + no_normal_output = "-n" in options + make_image = not no_normal_output - width, height = im.size + if make_image or preview: + exif = EXIF.process_file(open(input_filename)) + im = PIL.Image.open(input_filename).convert("RGB") + im = rotate_and_scale(exif, im, width, height, rotate) + + width, height = im.size - if saturate or desaturate or darken or brighten: - for y in range(0, height): - for x in range(0, width): - if saturate or desaturate: - rgb = im.getpixel((x, y)) - rgb = saturate_rgb(rgb, saturate and math.pow(0.5, saturate) or math.pow(2, desaturate)) - im.putpixel((x, y), rgb) + if saturate or desaturate or darken or brighten: + for y in range(0, height): + for x in range(0, width): + if saturate or desaturate: + rgb = im.getpixel((x, y)) + rgb = saturate_rgb(rgb, saturate and math.pow(0.5, saturate) or math.pow(2, desaturate)) + im.putpixel((x, y), rgb) - if darken or brighten: - rgb = im.getpixel((x, y)) - rgb = amplify_rgb(rgb, brighten and math.pow(0.5, brighten) or math.pow(2, darken)) - im.putpixel((x, y), rgb) + if darken or brighten: + rgb = im.getpixel((x, y)) + rgb = amplify_rgb(rgb, brighten and math.pow(0.5, brighten) or math.pow(2, darken)) + im.putpixel((x, y), rgb) if preview: imp = im.copy() + step = half_resolution_preview and 2 or 1 for y in range(0, height): - for x in range(0, width): + for x in range(0, width, step): rgb = imp.getpixel((x, y)) value = get_value(rgb) imp.putpixel((x, y), value) + if half_resolution_preview: + imp.putpixel((x+1, y), value) + imp.save(preview_filename) - for y in range(0, height): - c = get_colours(im, width, y) - most = [value for n, value in c[:4]] - least = [value for n, value in c[4:]] + if make_image: + for y in range(0, height): + c = get_colours(im, y) + most = [value for n, value in c[:4]] + least = [value for n, value in c[4:]] + + for x in range(0, width): + rgb = im.getpixel((x, y)) + value = get_value(rgb, most) + im.putpixel((x, y), value) - for x in range(0, width): - rgb = im.getpixel((x, y)) - value = get_value(rgb, most) - im.putpixel((x, y), value) + if y < height - 1: + rgbn = im.getpixel((x, y+1)) + rgbn = tuple(map(lambda i: clip(i[0] + i[1] - i[2]), zip(rgbn, rgb, value))) + im.putpixel((x, y+1), rgbn) + + im.save(output_filename) - if y < height - 1: - rgbn = im.getpixel((x, y+1)) - rgbn = tuple(map(lambda i: clip(i[0] + i[1] - i[2]), zip(rgbn, rgb, value))) - im.putpixel((x, y+1), rgbn) + if verify: + if no_normal_output: + im = PIL.Image.open(output_filename).convert("RGB") - im.save(output_filename) + result = count_colours(im, 4) + if result is not None: + y, colours = result + print "Row %d has the following colours: %s" % (y, "; ".join([repr(c) for c in colours])) # vim: tabstop=4 expandtab shiftwidth=4