1.1 --- a/optimiser.py Sun Oct 11 20:10:50 2015 +0200
1.2 +++ b/optimiser.py Sun Oct 11 23:23:26 2015 +0200
1.3 @@ -118,11 +118,18 @@
1.4 -D - Darken the input image (optional float, 1.0 if unspecified)
1.5 -B - Brighten the input image (optional float, 1.0 if unspecified)
1.6
1.7 --r - Rotate the input image clockwise
1.8 +-l - Use colours producing the least error
1.9 + (slower but useful for fewer than 4 colours)
1.10 +
1.11 +-r - Rotate the input image clockwise explicitly
1.12 + (EXIF information is used otherwise)
1.13 -p - Generate a separate preview image
1.14 -h - Make the preview image with half horizontal resolution (MODE 2)
1.15 -v - Verify the output image (loaded if -n is given)
1.16 -n - Generate no output image
1.17 +
1.18 +An input filename of - implies the -n option, and is useful for verifying
1.19 +previously generated images.
1.20 """ % split(sys.argv[0])[1]
1.21 sys.exit(1)
1.22
1.23 @@ -149,11 +156,12 @@
1.24
1.25 # General output options.
1.26
1.27 + least_error = "-l" in options
1.28 rotate = "-r" in options
1.29 preview = "-p" in options
1.30 half_resolution_preview = "-h" in options
1.31 verify = "-v" in options
1.32 - no_normal_output = "-n" in options
1.33 + no_normal_output = "-n" in options or input_filename == "-"
1.34 make_image = not no_normal_output
1.35
1.36 # Load the input image if requested.
1.37 @@ -184,7 +192,7 @@
1.38 # Generate an output image if requested.
1.39
1.40 if make_image:
1.41 - convert_image(im, number_of_colours)
1.42 + convert_image(im, number_of_colours, least_error)
1.43 im.save(output_filename)
1.44
1.45 # Verify the output image (which may be loaded) if requested.
2.1 --- a/optimiserlib.py Sun Oct 11 20:10:50 2015 +0200
2.2 +++ b/optimiserlib.py Sun Oct 11 23:23:26 2015 +0200
2.3 @@ -22,6 +22,7 @@
2.4
2.5 from random import random, randrange
2.6 import itertools
2.7 +import math
2.8
2.9 corners = [
2.10 (0, 0, 0), (255, 0, 0), (0, 255, 0), (255, 255, 0),
2.11 @@ -36,6 +37,9 @@
2.12 def clip(v):
2.13 return int(within(v, 0, 255))
2.14
2.15 +def distance(rgb1, rgb2):
2.16 + return math.sqrt(pow(abs(rgb1[0] - rgb2[0]), 2) + pow(abs(rgb1[1] - rgb2[1]), 2) + pow(abs(rgb1[2] - rgb2[2]), 2))
2.17 +
2.18 def restore(srgb):
2.19 r, g, b = srgb
2.20 return int(r * 255.0), int(g * 255.0), int(b * 255.0)
2.21 @@ -257,7 +261,7 @@
2.22 x += 1
2.23 y += 1
2.24
2.25 -def convert_image(im, colours):
2.26 +def convert_image(im, colours, least_error=False):
2.27
2.28 "Convert image 'im' to an appropriate output representation."
2.29
2.30 @@ -271,19 +275,22 @@
2.31
2.32 for l in get_combinations(c, colours):
2.33 most = [value for f, value in l]
2.34 - missing = 0
2.35 + error = 0
2.36
2.37 x = 0
2.38 while x < width:
2.39 rgb = im.getpixel((x, y))
2.40 - value = get_value(rgb, most, True)
2.41 - if value is None:
2.42 - missing += 1
2.43 + value = get_value(rgb, most)
2.44 + if least_error:
2.45 + error += distance(value, rgb)
2.46 + elif value is None:
2.47 + error += 1
2.48 x += 1
2.49
2.50 - if not missing:
2.51 + if not least_error and not error:
2.52 break # use this combination
2.53 - suggestions.append((missing, l))
2.54 +
2.55 + suggestions.append((error, l))
2.56
2.57 # Find the most accurate suggestion.
2.58