I recently updated flatten.py to strip out pngcrush and use argparse:
#!/usr/bin/env python2
from sys import argv, stderr, exit
from subprocess import Popen
from argparse import ArgumentParser, ArgumentError
from copy import copy
from os import remove
from os import close as os_close
from re import compile as re_compile
from os.path import join, isfile, exists
from tempfile import mkstemp
filext = re_compile('^(.+)\.(.+)$')
filext_png = re_compile('\.png$')
img_type = ['Bilevel', 'Grayscale', 'GrayscaleMatte', 'Palette', 'PaletteMatte', 'TrueColor', 'TrueColorMatte', 'ColorSeparate', 'ColorSeparationMatte', 'Optimize']
img_cspace = ['CMY', 'CMYK', 'Gray', 'HSB', 'HSL', 'HWB', 'Lab', 'Log', 'OHTA', 'Rec601Luma', 'Rec601YCbCr', 'Rec709Luma', 'Rec709YCbCr', 'RGB', 'sRGB', 'Transparent', 'XYZ', 'YCbCr', 'YCC', 'YIQ', 'YPbPr', 'YUV']
parser = ArgumentParser(usage = 'Usage: %(prog)s [ options ] input [ output ]')
parser.add_argument('-s', '--size', dest = 'size', default = None, help = 'The output size; passed directly to ImageMagick')
parser.add_argument('-n', '--no-clobber', dest = 'clobber', default = True, action = 'store_false', help = 'Don\'t overwrite the target file')
parser.add_argument('-X', '--lossy-reduction', dest = 'lossy_reduction', default = True, action = 'store_false', help = 'Don\'t allow OptiPNG to perform lossy optimizations')
parser.add_argument('-f', '--filter', dest = 'filter', default = 'Catrom', help = 'The filter to resize with if necessary')
parser.add_argument('-b', '--background', dest = 'background', default = 'white', help = 'The background when flattening')
parser.add_argument('-F', '--no-flatten', dest = 'flatten', default = True, action = 'store_false', help = 'Don\'t flatten the output')
parser.add_argument('-t', '--type', dest = 'type', choices = img_type + img_cspace, default = None, help = 'The type of the output image: analogous to both -type and -colorspace in ImageMagick')
parser.add_argument('-d', '--depth', dest = 'depth', choices = (1, 2, 4, 8, 16), type = int, default = None, help = 'The depth of the output image')
parser.add_argument('-p', '--pre-color', dest = 'precolor', default = False, action = 'store_true', help = 'Change bit-depth/colorspace prior to scaling if applicable')
parser.add_argument('input', help = 'Input file')
parser.add_argument('output', nargs = '?', help = 'Destination file; will default to ${input}_small.png')
args = parser.parse_args()
if isfile(args.input):
pngout = False
if args.output:
output = args.output
if filext_png.search(output):
pngout = True
else:
m = filext.search(args.input)
if not m is None:
output = '%s_small.%s' % (m.group(1), m.group(2))
if m.group(2) == 'png':
pngout = True
else:
output = '%s_small.png' % args.input
pngout = True
if not args.clobber and exists(output):
print >>stderr, 'Output file exists:', output
exit(2)
# ACTUAL PROCESSING
pargs = ['convert', args.input]
if args.precolor:
if args.flatten:
pargs += ['-background', args.background, '-flatten', '+matte']
if not args.size is None:
pargs += ['-filter', args.filter, '-resize', args.size]
if not args.type is None:
if args.type in img_type:
pargs += ['-type', args.type]
if not args.depth is None:
pargs += ['-depth', str(args.depth)]
elif args.type in img_cspace:
pargs += ['-colorspace', args.type]
if not args.depth is None:
pargs += ['-depth', str(args.depth)]
if not args.precolor:
if args.flatten:
pargs += ['-background', args.background, '-flatten', '+matte']
if not args.size is None:
pargs += ['-filter', args.filter, '-resize', args.size]
if pngout:
# Run convert
pargs.append('png:' + output)
try:
Popen(pargs).wait()
except KeyboardInterrupt:
if isfile(output):
remove(output)
exit(1)
# Run optipng
try:
optipng = ['optipng', '-o9']
if not args.lossy_reduction:
optipng.append('-nx')
optipng.append(output)
Popen(optipng).wait()
except KeyboardInterrupt:
if isfile(output):
remove(output)
else:
pargs.append(output)
Popen(pargs).wait()
# END
else:
print >>stderr, 'No such file:', args.input
exit(2)