1.1 --- a/optimiser.py Thu Oct 08 23:45:40 2015 +0200
1.2 +++ b/optimiser.py Fri Oct 09 00:01:29 2015 +0200
1.3 @@ -24,6 +24,7 @@
1.4 from os.path import split, splitext
1.5 import EXIF
1.6 import PIL.Image
1.7 +import itertools
1.8 import math
1.9 import sys
1.10
1.11 @@ -137,21 +138,25 @@
1.12 specified 'chosen' colours.
1.13 """
1.14
1.15 - l = [(f, value) for f, value in combination(rgb) if value in chosen]
1.16 + l = [(f, value) for f, value in combination(rgb) if not chosen or value in chosen]
1.17 l.sort(reverse=True)
1.18 return l
1.19
1.20 -def get_value(rgb, chosen=None):
1.21 +def get_value(rgb, chosen=None, fail=False):
1.22
1.23 """
1.24 Get an output colour for 'rgb', optionally limited to any specified 'chosen'
1.25 - colours.
1.26 + colours. If 'fail' is set to a true value, return None if the colour cannot
1.27 + be expressed using any of the chosen colours.
1.28 """
1.29
1.30 l = pattern(rgb, chosen)
1.31 limit = sum([f for f, c in l])
1.32 if not limit:
1.33 - return l[randrange(0, len(l))][1]
1.34 + if fail:
1.35 + return None
1.36 + else:
1.37 + return l[randrange(0, len(l))][1]
1.38
1.39 choose = random() * limit
1.40 threshold = 0
1.41 @@ -201,6 +206,22 @@
1.42 c.sort(reverse=True)
1.43 return c
1.44
1.45 +def get_combinations(c, n):
1.46 +
1.47 + """
1.48 + Get combinations of colours from 'c' of size 'n' in decreasing order of
1.49 + probability.
1.50 + """
1.51 +
1.52 + all = []
1.53 + for l in itertools.combinations(c, n):
1.54 + total = 0
1.55 + for f, value in l:
1.56 + total += f
1.57 + all.append((total, l))
1.58 + all.sort(reverse=True)
1.59 + return [l for total, l in all]
1.60 +
1.61 def test():
1.62
1.63 "Generate slices of the colour cube."
1.64 @@ -366,8 +387,18 @@
1.65 if make_image:
1.66 for y in range(0, height):
1.67 c = get_colours(im, y)
1.68 - most = [value for n, value in c[:4]]
1.69 - least = [value for n, value in c[4:]]
1.70 +
1.71 + for l in get_combinations(c, 4):
1.72 + most = [value for f, value in l]
1.73 + for x in range(0, width):
1.74 + rgb = im.getpixel((x, y))
1.75 + value = get_value(rgb, most, True)
1.76 + if value is None:
1.77 + break # try next combination
1.78 + else:
1.79 + break # use this combination
1.80 + else:
1.81 + most = [value for f, value in c[:4]] # use the first four
1.82
1.83 for x in range(0, width):
1.84 rgb = im.getpixel((x, y))