# HG changeset patch # User Paul Boddie # Date 1444570098 -7200 # Node ID e5fce4442d7ea21c9b8fb376253794e21d71cba5 # Parent 065abc8520c57074949f63f6070bea4cc56a3259# Parent abb04ac9cf8d5df2bda7ccb05ce5655462d98216 Combined the preview and conversion functions, added configuration of the number of chosen colours and the output image width. Fixed option descriptions. diff -r 065abc8520c5 -r e5fce4442d7e optimiser.py --- a/optimiser.py Sat Oct 10 23:55:15 2015 +0200 +++ b/optimiser.py Sun Oct 11 15:28:18 2015 +0200 @@ -297,27 +297,7 @@ pim.putdata(im.getdata()) -def preview_image(pim, half_resolution_preview=False): - - "Return a preview copy of image 'pim'." - - width, height = pim.size - imp = pim.copy() - im = SimpleImage(list(pim.getdata()), pim.size) - step = half_resolution_preview and 2 or 1 - - for y in range(0, height): - for x in range(0, width, step): - rgb = im.getpixel((x, y)) - value = get_value(rgb) - im.putpixel((x, y), value) - if half_resolution_preview: - im.putpixel((x+1, y), value) - - imp.putdata(im.getdata()) - return imp - -def convert_image(pim): +def convert_image(pim, colours): "Convert image 'pim' to an appropriate output representation." @@ -327,7 +307,7 @@ for y in range(0, height): c = get_colours(im, y) - for l in get_combinations(c, 4): + for l in get_combinations(c, colours): most = [value for f, value in l] for x in range(0, width): rgb = im.getpixel((x, y)) @@ -337,7 +317,7 @@ else: break # use this combination else: - most = [value for f, value in c[:4]] # use the first four + most = [value for f, value in c[:colours]] # use the first colours for x in range(0, width): rgb = im.getpixel((x, y)) @@ -364,15 +344,23 @@ pim.putdata(im.getdata()) -def get_float(options, flag): +def get_parameter(options, flag, conversion, default, missing): + + """ + From 'options', return any parameter following the given 'flag', applying + the 'conversion' which has the given 'default' if no valid parameter is + found, or returning the given 'missing' value if the flag does not appear at + all. + """ + try: i = options.index(flag) try: - return float(options[i+1]) + return conversion(options[i+1]) except (IndexError, ValueError): - return 1.0 + return default except ValueError: - return 0.0 + return missing class SimpleImage: @@ -414,10 +402,13 @@ Options are... --s - Saturate the input image (can be followed by a float, default 1.0) --d - Desaturate the input image (can be followed by a float, default 1.0) --D - Darken the input image (can be followed by a float, default 1.0) --B - Brighten the input image (can be followed by a float, default 1.0) +-W - Indicate the output width (default is 320) +-C - Number of colours per scanline (default is 4) + +-s - Saturate the input image (optional float, 1.0 if unspecified) +-d - Desaturate the input image (optional float, 1.0 if unspecified) +-D - Darken the input image (optional float, 1.0 if unspecified) +-B - Brighten the input image (optional float, 1.0 if unspecified) -r - Rotate the input image clockwise -p - Generate a separate preview image @@ -427,7 +418,7 @@ """ % split(sys.argv[0])[1] sys.exit(1) - width = 320 + base_width = 320 height = 256 input_filename, output_filename = sys.argv[1:3] @@ -436,12 +427,17 @@ options = sys.argv[3:] - # Preprocessing options that can be repeated for extra effect. + # Basic image properties. + + width = get_parameter(options, "-W", int, base_width, base_width) + number_of_colours = get_parameter(options, "-C", int, 4, 4) - saturate = get_float(options, "-s") - desaturate = get_float(options, "-d") - darken = get_float(options, "-D") - brighten = get_float(options, "-B") + # Preprocessing options that employ parameters. + + saturate = get_parameter(options, "-s", float, 1.0, 0.0) + desaturate = get_parameter(options, "-d", float, 1.0, 0.0) + darken = get_parameter(options, "-D", float, 1.0, 0.0) + brighten = get_parameter(options, "-B", float, 1.0, 0.0) # General output options. @@ -457,19 +453,30 @@ if make_image or preview: exif = EXIF.process_file(open(input_filename)) im = PIL.Image.open(input_filename).convert("RGB") - im = rotate_and_scale(exif, im, width, height, rotate) + im = rotate_and_scale(exif, im, base_width, height, rotate) + + # Scale images to the appropriate width. + + if width != base_width: + im = im.resize((width, height)) process_image(im, saturate, desaturate, darken, brighten) # Generate a preview if requested. if preview: - preview_image(im, half_resolution_preview).save(preview_filename) + imp = im.copy() + if half_resolution_preview: + imp = imp.resize((width / 2, height)) + convert_image(imp, 8) + if half_resolution_preview: + imp = imp.resize((width, height)) + imp.save(preview_filename) # Generate an output image if requested. if make_image: - convert_image(im) + convert_image(im, number_of_colours) im.save(output_filename) # Verify the output image (which may be loaded) if requested. @@ -478,7 +485,7 @@ if no_normal_output: im = PIL.Image.open(output_filename).convert("RGB") - result = count_colours(im, 4) + result = count_colours(im, number_of_colours) if result is not None: y, colours = result print "Image %s: row %d has the following colours: %s" % (output_filename, y, "; ".join([repr(c) for c in colours]))