1.1 --- a/optimiser.py Sat Oct 10 00:14:25 2015 +0200
1.2 +++ b/optimiser.py Sat Oct 10 01:45:55 2015 +0200
1.3 @@ -36,24 +36,16 @@
1.4 return min(max(v, lower), upper)
1.5
1.6 def clip(v):
1.7 - return int(within(v, 0, 255))
1.8 -
1.9 -def distance(rgb1, rgb2):
1.10 - r1, g1, b1 = rgb1
1.11 - r2, g2, b2 = rgb2
1.12 - return math.sqrt(pow(r1 - r2, 2) + pow(g1 - g2, 2) + pow(b1 - b2, 2))
1.13 + return int(within(v, 0.0, 255.0))
1.14
1.15 def restore(srgb):
1.16 - r, g, b = srgb
1.17 - return int(r * 255.0), int(g * 255.0), int(b * 255.0)
1.18 + return int(srgb[0] * 255.0), int(srgb[1] * 255.0), int(srgb[2] * 255.0)
1.19
1.20 def scale(rgb):
1.21 - r, g, b = rgb
1.22 - return r / 255.0, g / 255.0, b / 255.0
1.23 + return float(rgb[0]) / 255.0, float(rgb[1]) / 255.0, float(rgb[2]) / 255.0
1.24
1.25 def invert(srgb):
1.26 - r, g, b = srgb
1.27 - return 1.0 - r, 1.0 - g, 1.0 - b
1.28 + return 1.0 - srgb[0], 1.0 - srgb[1], 1.0 - srgb[2]
1.29
1.30 # Colour distribution functions.
1.31
1.32 @@ -64,9 +56,11 @@
1.33 # Get the colour with components scaled from 0 to 1, plus the inverted
1.34 # component values.
1.35
1.36 - rgb = scale(rgb)
1.37 - rgbi = invert(rgb)
1.38 - pairs = zip(rgbi, rgb)
1.39 + srgb = scale(rgb)
1.40 + rgbi = invert(srgb)
1.41 + rc = (rgbi[0], srgb[0])
1.42 + gc = (rgbi[1], srgb[1])
1.43 + bc = (rgbi[2], srgb[2])
1.44
1.45 # For each corner of the colour cube (primary and secondary colours plus
1.46 # black and white), calculate the corner value's contribution to the
1.47 @@ -74,12 +68,15 @@
1.48
1.49 d = []
1.50 for corner in corners:
1.51 - rs, gs, bs = scale(corner)
1.52 + crgb = scale(corner)
1.53 + rs, gs, bs = crgb
1.54 + ri, gi, bi = int(rs), int(gs), int(bs)
1.55
1.56 # Obtain inverted channel values where corner channels are low;
1.57 # obtain original channel values where corner channels are high.
1.58
1.59 - d.append((pairs[0][int(rs)] * pairs[1][int(gs)] * pairs[2][int(bs)], corner))
1.60 + f = rc[ri] * gc[gi] * bc[bi]
1.61 + d.append((f, corner))
1.62
1.63 # Balance the corner contributions.
1.64
1.65 @@ -89,7 +86,6 @@
1.66
1.67 "Return 'rgb' and its complement."
1.68
1.69 - r, g, b = rgb
1.70 return rgb, restore(invert(scale(rgb)))
1.71
1.72 def balance(d):
1.73 @@ -121,7 +117,7 @@
1.74 out[0] += v * rgb[0]
1.75 out[1] += v * rgb[1]
1.76 out[2] += v * rgb[2]
1.77 - return out
1.78 + return int(out[0]), int(out[1]), int(out[2])
1.79
1.80 def pattern(rgb, chosen=None):
1.81
1.82 @@ -170,15 +166,13 @@
1.83 return x >= 0 and 1 or -1
1.84
1.85 def saturate_rgb(rgb, exp):
1.86 - r, g, b = rgb
1.87 - return saturate_value(r, exp), saturate_value(g, exp), saturate_value(b, exp)
1.88 + return saturate_value(rgb[0], exp), saturate_value(rgb[1], exp), saturate_value(rgb[2], exp)
1.89
1.90 def saturate_value(x, exp):
1.91 return int(127.5 + sign(x - 127.5) * 127.5 * pow(abs(x - 127.5) / 127.5, exp))
1.92
1.93 def amplify_rgb(rgb, exp):
1.94 - r, g, b = rgb
1.95 - return amplify_value(r, exp), amplify_value(g, exp), amplify_value(b, exp)
1.96 + return amplify_value(rgb[0], exp), amplify_value(rgb[1], exp), amplify_value(rgb[2], exp)
1.97
1.98 def amplify_value(x, exp):
1.99 return int(pow(x / 255.0, exp) * 255.0)
1.100 @@ -251,8 +245,7 @@
1.101 for y in range(0, height):
1.102 l = set(im.getdata()[y * width:(y+1) * width])
1.103 if len(l) > colours:
1.104 - return (y, l)
1.105 - return None
1.106 + raise ValueError(y, l)
1.107
1.108 def process_image(im, saturate, desaturate, darken, brighten):
1.109
1.110 @@ -329,21 +322,19 @@
1.111
1.112 if x < width - 1:
1.113 rgbn = im.getpixel((x+1, y))
1.114 - rgbn = (
1.115 + im.putpixel((x+1, y), (
1.116 clip(rgbn[0] + (rgb[0] - value[0]) / 4.0),
1.117 clip(rgbn[1] + (rgb[1] - value[1]) / 4.0),
1.118 clip(rgbn[2] + (rgb[2] - value[2]) / 4.0)
1.119 - )
1.120 - im.putpixel((x+1, y), rgbn)
1.121 + ))
1.122
1.123 if y < height - 1:
1.124 rgbn = im.getpixel((x, y+1))
1.125 - rgbn = (
1.126 + im.putpixel((x, y+1), (
1.127 clip(rgbn[0] + (rgb[0] - value[0]) / 2.0),
1.128 clip(rgbn[1] + (rgb[1] - value[1]) / 2.0),
1.129 clip(rgbn[2] + (rgb[2] - value[2]) / 2.0)
1.130 - )
1.131 - im.putpixel((x, y+1), rgbn)
1.132 + ))
1.133
1.134 class SimpleImage:
1.135
1.136 @@ -370,14 +361,16 @@
1.137 # Test program.
1.138
1.139 if __name__ == "__main__":
1.140 - data = [(0, 0, 0)] * 1024
1.141 - size = (32, 32)
1.142 + data = [(0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)]
1.143 + size = (2, 2)
1.144
1.145 im = SimpleImage(data, size)
1.146
1.147 process_image(im, 1.0, 0.0, 1.0, 0.0)
1.148 imp = preview_image(im, False)
1.149 convert_image(im)
1.150 + count_colours(im, 4)
1.151 + im.getdata()
1.152
1.153 test_im = SimpleImage(data, size)
1.154 test_slice(test_im, 32, 0)
1.155 @@ -385,4 +378,7 @@
1.156 test_flat_im = SimpleImage(data, size)
1.157 test_flat_slice(test_flat_im, 32, (200, 100, 50))
1.158
1.159 + rgb = (200, 150, 100)
1.160 + combine(pattern(rgb)) == rgb
1.161 +
1.162 # vim: tabstop=4 expandtab shiftwidth=4