1.1 --- a/optimiser.py Thu Oct 01 18:39:59 2015 +0200
1.2 +++ b/optimiser.py Fri Oct 02 13:37:29 2015 +0200
1.3 @@ -1,6 +1,6 @@
1.4 #!/usr/bin/env python
1.5
1.6 -from random import randint
1.7 +from random import random
1.8 from os.path import extsep, splitext
1.9 import EXIF
1.10 import PIL.Image
1.11 @@ -17,53 +17,30 @@
1.12 r2, g2, b2 = rgb2
1.13 return math.sqrt(pow(r1 - r2, 2) + pow(g1 - g2, 2) + pow(b1 - b2, 2))
1.14
1.15 -def brightness(rgb):
1.16 - return distance(rgb, (0, 0, 0))
1.17 -
1.18 -def factor(start, end, rgb):
1.19 - r1, g1, b1 = start
1.20 - r2, g2, b2 = end
1.21 - gr, gg, gb = r2 - r1, g2 - g1, b2 - b1
1.22 - r, g, b = rgb
1.23 - pr, pg, pb = r - r1, g - g1, b - b1
1.24 - dp = pr * gr + pg * gg + pb * gb
1.25 - return dp / pow(distance(start, end), 2)
1.26 -
1.27 -def darklight(rgb1, rgb2):
1.28 - if brightness(rgb1) <= brightness(rgb2):
1.29 - return rgb1, rgb2
1.30 - else:
1.31 - return rgb2, rgb1
1.32 -
1.33 -def nearest(rgb, values=None):
1.34 - l = map(lambda c: (distance(rgb, c), c), values or corners)
1.35 - l.sort()
1.36 - return l
1.37 +def distribution(rgb, points):
1.38 + l = []
1.39 + total = 0
1.40 + for c in points:
1.41 + d = distance(rgb, c)
1.42 + if d == 0:
1.43 + return [(1, c)]
1.44 + l.append((pow(d, -3), c))
1.45 + total += pow(d, -3)
1.46 + return [(d / total, c) for d, c in l]
1.47
1.48 def pattern(rgb, values=None):
1.49 - l = nearest(rgb, values)
1.50 - start, end = l[0][1], l[1][1]
1.51 - f = factor(start, end, rgb)
1.52 - #if f > 0.5:
1.53 - # start, end = end, start
1.54 - # f = 1 - f
1.55 - return start, end, f
1.56 + l = distribution(rgb, values or corners)
1.57 + l.sort(reverse=True)
1.58 + return l
1.59
1.60 -def choose(seq, f):
1.61 - last = int(seq * f)
1.62 - current = int((seq + 1) * f)
1.63 - return last != current
1.64 -
1.65 -def get_value(xy, rgb, width, height, values=None):
1.66 - x, y = xy
1.67 - rgb1, rgb2, f = pattern(rgb, values)
1.68 - if choose(x + randint(0, width), f) and choose(y + randint(0, height), f):
1.69 - return rgb2
1.70 - else:
1.71 - return rgb1
1.72 -
1.73 -def get_best(rgb, values):
1.74 - return nearest(rgb, values)[0][1]
1.75 +def get_value(rgb, values=None):
1.76 + choose = random()
1.77 + threshold = 0
1.78 + for f, c in pattern(rgb, values):
1.79 + threshold += f
1.80 + if choose < threshold:
1.81 + return c
1.82 + return c
1.83
1.84 def sign(x):
1.85 return x >= 0 and 1 or -1
1.86 @@ -80,7 +57,7 @@
1.87 im = PIL.Image.new("RGB", (size, size))
1.88 for g in range(0, size):
1.89 for b in range(0, size):
1.90 - value = get_value((g, b), (r, (g * 256) / size, (b * 256 / size)), size, size)
1.91 + value = get_value((r, (g * 256) / size, (b * 256 / size)))
1.92 im.putpixel((g, b), value)
1.93 im.save("rgb%d.png" % r)
1.94
1.95 @@ -89,7 +66,7 @@
1.96 im = PIL.Image.new("RGB", (size, size))
1.97 for y in range(0, size):
1.98 for x in range(0, size):
1.99 - im.putpixel((x, y), get_value((x, y), rgb, size, size))
1.100 + im.putpixel((x, y), get_value(rgb))
1.101 im.save("rgb%02d%02d%02d.png" % rgb)
1.102
1.103 def rotate_and_scale(im, width, height, rotate):
1.104 @@ -125,7 +102,7 @@
1.105 desaturate = sys.argv[3:].count("-d")
1.106
1.107 x = EXIF.process_file(open(input_filename))
1.108 - im = PIL.Image.open(input_filename)
1.109 + im = PIL.Image.open(input_filename).convert("RGB")
1.110 im = rotate_and_scale(im, width, height, rotate)
1.111
1.112 if preview:
1.113 @@ -148,7 +125,7 @@
1.114
1.115 # Count the number of requested colours.
1.116
1.117 - value = get_value((x, y), rgb, width, height)
1.118 + value = get_value(rgb)
1.119 if not c.has_key(value):
1.120 c[value] = 1
1.121 else:
1.122 @@ -174,9 +151,9 @@
1.123 # Get the requested colours and choose the closest alternative for
1.124 # less common colours.
1.125
1.126 - value = get_value((x, y), rgb, width, height)
1.127 + value = get_value(rgb)
1.128 if value in least:
1.129 - value = get_value((x, y), rgb, width, height, most)
1.130 + value = get_value(rgb, most)
1.131 im.putpixel((x, y), value)
1.132
1.133 im.save(output_filename)