#!/venv/bin/python3 # http://www.python.org/doc/2.4.4/lib/module-itertools.html import itertools import sys import png Description = """Join PNG images in a column top-to-bottom.""" class FormatError(Exception): """ Some problem with the image format. """ def join_col(out, l): """ Join the list of images. All input images must be same width and have the same number of channels. They are joined top-to-bottom. `out` is the (open file) destination for the output image. `l` should be a list of open files (the input image files). """ image = 0 stream = 0 # When the first image is read, this will be the reference width, # which must be the same for all images. width = None # Total height (accumulated as images are read). height = 0 # Accumulated rows. rows = [] for f in l: stream += 1 while True: im = png.Reader(file=f) try: im.preamble() except EOFError: break image += 1 if not width: width = im.width elif width != im.width: raise FormatError('Image %d in stream %d has width %d; does not match %d.' % (image, stream, im.width, width)) height += im.height # Various bugs here because different numbers of channels and depths go wrong. w, h, p, info = im.asDirect() rows.extend(p) # Alarmingly re-use the last info object. tinfo = dict(info) del tinfo['size'] w = png.Writer(width, height, **tinfo) w.write(out, rows) def main(argv): import argparse parser = argparse.ArgumentParser(description=Description) parser.add_argument( "input", nargs="*", default="-", type=png.cli_open, metavar="PNG" ) args = parser.parse_args() return join_col(png.binary_stdout(), args.input) if __name__ == '__main__': main(sys.argv)