PaletteOptimiser

Changeset

48:9a8c24425be9
2015-10-06 Paul Boddie raw files shortlog changelog graph Introduced compensation to complementary colours for those removed.
optimiser.py (file)
     1.1 --- a/optimiser.py	Sun Oct 04 21:47:16 2015 +0200
     1.2 +++ b/optimiser.py	Tue Oct 06 14:31:54 2015 +0200
     1.3 @@ -59,6 +59,16 @@
     1.4          d[(255, 255, 255)] += common
     1.5      return [(f, value) for value, f in d.items()]
     1.6  
     1.7 +def compensate(d, chosen):
     1.8 +    dd = dict([(value, f) for f, value in d])
     1.9 +    for f, value in d:
    1.10 +        if value not in chosen:
    1.11 +            _value, complement = complements(value)
    1.12 +            if complement in chosen:
    1.13 +                f = max(0, f - dd[complement])
    1.14 +                dd[value] = f
    1.15 +    return [(f, value) for value, f in dd.items() if value in chosen]
    1.16 +
    1.17  def combine(d):
    1.18      out = [0, 0, 0]
    1.19      for v, rgb in d:
    1.20 @@ -67,15 +77,19 @@
    1.21          out[2] += v * rgb[2]
    1.22      return out
    1.23  
    1.24 -def pattern(rgb):
    1.25 +def pattern(rgb, chosen=None):
    1.26      l = combination(rgb)
    1.27 +    if chosen:
    1.28 +        l = compensate(l, chosen)
    1.29      l.sort(reverse=True)
    1.30      return l
    1.31  
    1.32 -def get_value(rgb):
    1.33 -    choose = random()
    1.34 +def get_value(rgb, chosen=None):
    1.35 +    l = pattern(rgb, chosen)
    1.36 +    limit = sum([f for f, c in l])
    1.37 +    choose = random() * limit
    1.38      threshold = 0
    1.39 -    for f, c in pattern(rgb):
    1.40 +    for f, c in l:
    1.41          threshold += f
    1.42          if choose < threshold:
    1.43              return c
    1.44 @@ -147,6 +161,7 @@
    1.45      desaturate = sys.argv[3:].count("-d")
    1.46      preview = "-p" in sys.argv[3:]
    1.47      square = "-2" in sys.argv[3:] and square or (lambda x: x)
    1.48 +    randomise = "-R" in sys.argv[3:]
    1.49  
    1.50      x = EXIF.process_file(open(input_filename))
    1.51      im = PIL.Image.open(input_filename).convert("RGB")
    1.52 @@ -192,7 +207,7 @@
    1.53          most = [value for n, value in c[:4]]
    1.54          least = [value for n, value in c[4:]]
    1.55  
    1.56 -        if least:
    1.57 +        if least and randomise:
    1.58              switched = []
    1.59              for j in 1, 2:
    1.60                  i = randrange(0, 4)
    1.61 @@ -206,14 +221,7 @@
    1.62  
    1.63          for x in range(0, width):
    1.64              rgb = im.getpixel((x, y))
    1.65 -
    1.66 -            # Get the requested colours and choose the closest alternative for
    1.67 -            # less common colours.
    1.68 -
    1.69 -            value = get_value(rgb)
    1.70 -            if value in least:
    1.71 -                value = nearest(value, most)
    1.72 -
    1.73 +            value = get_value(rgb, most)
    1.74              im.putpixel((x, y), value)
    1.75  
    1.76      im.save(output_filename)