PaletteOptimiser

Changeset

47:4b9192e71fb8
2015-10-04 Paul Boddie raw files shortlog changelog graph Introduced a distance-based approach to obtain suitable alternative colours.
optimiser.py (file)
     1.1 --- a/optimiser.py	Sun Oct 04 21:47:16 2015 +0200
     1.2 +++ b/optimiser.py	Sun Oct 04 23:55:36 2015 +0200
     1.3 @@ -1,6 +1,6 @@
     1.4  #!/usr/bin/env python
     1.5  
     1.6 -from random import random, randrange
     1.7 +from random import choice, random, randrange
     1.8  from os.path import splitext
     1.9  import EXIF
    1.10  import PIL.Image
    1.11 @@ -20,8 +20,14 @@
    1.12  
    1.13  def nearest(rgb, values):
    1.14      l = [(distance(rgb, value), value) for value in values]
    1.15 -    l.sort()
    1.16 -    return l[0][1]
    1.17 +    total = sum([d for d, value in l])
    1.18 +    l = [(d / total, value) for d, value in l]
    1.19 +    l.sort(reverse=True)
    1.20 +    lc = [(d, value) for d, value in l if common(rgb, value)]
    1.21 +    return get_from_distribution(rgb, lc or l)
    1.22 +
    1.23 +def common(rgb1, rgb2):
    1.24 +    return sum(map(lambda x: x[0] * x[1], zip(rgb1, rgb2))) != 0
    1.25  
    1.26  def restore(srgb):
    1.27      return tuple(map(lambda x: int(x * 255.0), srgb))
    1.28 @@ -72,15 +78,18 @@
    1.29      l.sort(reverse=True)
    1.30      return l
    1.31  
    1.32 -def get_value(rgb):
    1.33 +def get_from_distribution(rgb, dist):
    1.34      choose = random()
    1.35      threshold = 0
    1.36 -    for f, c in pattern(rgb):
    1.37 +    for f, c in dist:
    1.38          threshold += f
    1.39          if choose < threshold:
    1.40              return c
    1.41      return c
    1.42  
    1.43 +def get_value(rgb):
    1.44 +    return get_from_distribution(rgb, pattern(rgb))
    1.45 +
    1.46  def sign(x):
    1.47      return x >= 0 and 1 or -1
    1.48  
    1.49 @@ -212,7 +221,7 @@
    1.50  
    1.51              value = get_value(rgb)
    1.52              if value in least:
    1.53 -                value = nearest(value, most)
    1.54 +                value = nearest(rgb, most)
    1.55  
    1.56              im.putpixel((x, y), value)
    1.57