1.1 --- a/optimiser.py Sat Oct 10 23:55:15 2015 +0200
1.2 +++ b/optimiser.py Sun Oct 11 15:28:18 2015 +0200
1.3 @@ -297,27 +297,7 @@
1.4
1.5 pim.putdata(im.getdata())
1.6
1.7 -def preview_image(pim, half_resolution_preview=False):
1.8 -
1.9 - "Return a preview copy of image 'pim'."
1.10 -
1.11 - width, height = pim.size
1.12 - imp = pim.copy()
1.13 - im = SimpleImage(list(pim.getdata()), pim.size)
1.14 - step = half_resolution_preview and 2 or 1
1.15 -
1.16 - for y in range(0, height):
1.17 - for x in range(0, width, step):
1.18 - rgb = im.getpixel((x, y))
1.19 - value = get_value(rgb)
1.20 - im.putpixel((x, y), value)
1.21 - if half_resolution_preview:
1.22 - im.putpixel((x+1, y), value)
1.23 -
1.24 - imp.putdata(im.getdata())
1.25 - return imp
1.26 -
1.27 -def convert_image(pim):
1.28 +def convert_image(pim, colours):
1.29
1.30 "Convert image 'pim' to an appropriate output representation."
1.31
1.32 @@ -327,7 +307,7 @@
1.33 for y in range(0, height):
1.34 c = get_colours(im, y)
1.35
1.36 - for l in get_combinations(c, 4):
1.37 + for l in get_combinations(c, colours):
1.38 most = [value for f, value in l]
1.39 for x in range(0, width):
1.40 rgb = im.getpixel((x, y))
1.41 @@ -337,7 +317,7 @@
1.42 else:
1.43 break # use this combination
1.44 else:
1.45 - most = [value for f, value in c[:4]] # use the first four
1.46 + most = [value for f, value in c[:colours]] # use the first colours
1.47
1.48 for x in range(0, width):
1.49 rgb = im.getpixel((x, y))
1.50 @@ -364,15 +344,23 @@
1.51
1.52 pim.putdata(im.getdata())
1.53
1.54 -def get_float(options, flag):
1.55 +def get_parameter(options, flag, conversion, default, missing):
1.56 +
1.57 + """
1.58 + From 'options', return any parameter following the given 'flag', applying
1.59 + the 'conversion' which has the given 'default' if no valid parameter is
1.60 + found, or returning the given 'missing' value if the flag does not appear at
1.61 + all.
1.62 + """
1.63 +
1.64 try:
1.65 i = options.index(flag)
1.66 try:
1.67 - return float(options[i+1])
1.68 + return conversion(options[i+1])
1.69 except (IndexError, ValueError):
1.70 - return 1.0
1.71 + return default
1.72 except ValueError:
1.73 - return 0.0
1.74 + return missing
1.75
1.76 class SimpleImage:
1.77
1.78 @@ -414,10 +402,13 @@
1.79
1.80 Options are...
1.81
1.82 --s - Saturate the input image (can be followed by a float, default 1.0)
1.83 --d - Desaturate the input image (can be followed by a float, default 1.0)
1.84 --D - Darken the input image (can be followed by a float, default 1.0)
1.85 --B - Brighten the input image (can be followed by a float, default 1.0)
1.86 +-W - Indicate the output width (default is 320)
1.87 +-C - Number of colours per scanline (default is 4)
1.88 +
1.89 +-s - Saturate the input image (optional float, 1.0 if unspecified)
1.90 +-d - Desaturate the input image (optional float, 1.0 if unspecified)
1.91 +-D - Darken the input image (optional float, 1.0 if unspecified)
1.92 +-B - Brighten the input image (optional float, 1.0 if unspecified)
1.93
1.94 -r - Rotate the input image clockwise
1.95 -p - Generate a separate preview image
1.96 @@ -427,7 +418,7 @@
1.97 """ % split(sys.argv[0])[1]
1.98 sys.exit(1)
1.99
1.100 - width = 320
1.101 + base_width = 320
1.102 height = 256
1.103
1.104 input_filename, output_filename = sys.argv[1:3]
1.105 @@ -436,12 +427,17 @@
1.106
1.107 options = sys.argv[3:]
1.108
1.109 - # Preprocessing options that can be repeated for extra effect.
1.110 + # Basic image properties.
1.111 +
1.112 + width = get_parameter(options, "-W", int, base_width, base_width)
1.113 + number_of_colours = get_parameter(options, "-C", int, 4, 4)
1.114
1.115 - saturate = get_float(options, "-s")
1.116 - desaturate = get_float(options, "-d")
1.117 - darken = get_float(options, "-D")
1.118 - brighten = get_float(options, "-B")
1.119 + # Preprocessing options that employ parameters.
1.120 +
1.121 + saturate = get_parameter(options, "-s", float, 1.0, 0.0)
1.122 + desaturate = get_parameter(options, "-d", float, 1.0, 0.0)
1.123 + darken = get_parameter(options, "-D", float, 1.0, 0.0)
1.124 + brighten = get_parameter(options, "-B", float, 1.0, 0.0)
1.125
1.126 # General output options.
1.127
1.128 @@ -457,19 +453,30 @@
1.129 if make_image or preview:
1.130 exif = EXIF.process_file(open(input_filename))
1.131 im = PIL.Image.open(input_filename).convert("RGB")
1.132 - im = rotate_and_scale(exif, im, width, height, rotate)
1.133 + im = rotate_and_scale(exif, im, base_width, height, rotate)
1.134 +
1.135 + # Scale images to the appropriate width.
1.136 +
1.137 + if width != base_width:
1.138 + im = im.resize((width, height))
1.139
1.140 process_image(im, saturate, desaturate, darken, brighten)
1.141
1.142 # Generate a preview if requested.
1.143
1.144 if preview:
1.145 - preview_image(im, half_resolution_preview).save(preview_filename)
1.146 + imp = im.copy()
1.147 + if half_resolution_preview:
1.148 + imp = imp.resize((width / 2, height))
1.149 + convert_image(imp, 8)
1.150 + if half_resolution_preview:
1.151 + imp = imp.resize((width, height))
1.152 + imp.save(preview_filename)
1.153
1.154 # Generate an output image if requested.
1.155
1.156 if make_image:
1.157 - convert_image(im)
1.158 + convert_image(im, number_of_colours)
1.159 im.save(output_filename)
1.160
1.161 # Verify the output image (which may be loaded) if requested.
1.162 @@ -478,7 +485,7 @@
1.163 if no_normal_output:
1.164 im = PIL.Image.open(output_filename).convert("RGB")
1.165
1.166 - result = count_colours(im, 4)
1.167 + result = count_colours(im, number_of_colours)
1.168 if result is not None:
1.169 y, colours = result
1.170 print "Image %s: row %d has the following colours: %s" % (output_filename, y, "; ".join([repr(c) for c in colours]))