# HG changeset patch # User Paul Boddie # Date 1444598606 -7200 # Node ID 4a75d044c6447b4e2ffa34589498f08f098e9d20 # Parent 344be4db9c1f289f8c52fbd244369e769a4756dc Added support for choosing the colour combination with the least error. Added interpretation of "-" as the input filename to suppress processing and output generation, thus providing a more concise way of verifying an image. diff -r 344be4db9c1f -r 4a75d044c644 optimiser.py --- a/optimiser.py Sun Oct 11 20:10:50 2015 +0200 +++ b/optimiser.py Sun Oct 11 23:23:26 2015 +0200 @@ -118,11 +118,18 @@ -D - Darken the input image (optional float, 1.0 if unspecified) -B - Brighten the input image (optional float, 1.0 if unspecified) --r - Rotate the input image clockwise +-l - Use colours producing the least error + (slower but useful for fewer than 4 colours) + +-r - Rotate the input image clockwise explicitly + (EXIF information is used otherwise) -p - Generate a separate preview image -h - Make the preview image with half horizontal resolution (MODE 2) -v - Verify the output image (loaded if -n is given) -n - Generate no output image + +An input filename of - implies the -n option, and is useful for verifying +previously generated images. """ % split(sys.argv[0])[1] sys.exit(1) @@ -149,11 +156,12 @@ # General output options. + least_error = "-l" in options rotate = "-r" in options preview = "-p" in options half_resolution_preview = "-h" in options verify = "-v" in options - no_normal_output = "-n" in options + no_normal_output = "-n" in options or input_filename == "-" make_image = not no_normal_output # Load the input image if requested. @@ -184,7 +192,7 @@ # Generate an output image if requested. if make_image: - convert_image(im, number_of_colours) + convert_image(im, number_of_colours, least_error) im.save(output_filename) # Verify the output image (which may be loaded) if requested. diff -r 344be4db9c1f -r 4a75d044c644 optimiserlib.py --- a/optimiserlib.py Sun Oct 11 20:10:50 2015 +0200 +++ b/optimiserlib.py Sun Oct 11 23:23:26 2015 +0200 @@ -22,6 +22,7 @@ from random import random, randrange import itertools +import math corners = [ (0, 0, 0), (255, 0, 0), (0, 255, 0), (255, 255, 0), @@ -36,6 +37,9 @@ def clip(v): return int(within(v, 0, 255)) +def distance(rgb1, rgb2): + return math.sqrt(pow(abs(rgb1[0] - rgb2[0]), 2) + pow(abs(rgb1[1] - rgb2[1]), 2) + pow(abs(rgb1[2] - rgb2[2]), 2)) + def restore(srgb): r, g, b = srgb return int(r * 255.0), int(g * 255.0), int(b * 255.0) @@ -257,7 +261,7 @@ x += 1 y += 1 -def convert_image(im, colours): +def convert_image(im, colours, least_error=False): "Convert image 'im' to an appropriate output representation." @@ -271,19 +275,22 @@ for l in get_combinations(c, colours): most = [value for f, value in l] - missing = 0 + error = 0 x = 0 while x < width: rgb = im.getpixel((x, y)) - value = get_value(rgb, most, True) - if value is None: - missing += 1 + value = get_value(rgb, most) + if least_error: + error += distance(value, rgb) + elif value is None: + error += 1 x += 1 - if not missing: + if not least_error and not error: break # use this combination - suggestions.append((missing, l)) + + suggestions.append((error, l)) # Find the most accurate suggestion.