#!/usr/bin/env python """ Generate wallpapers for dual-head desktops. Usage: dualhead.py WIDTHxHEIGHT[-WIDTHxHEIGHT] FILENAME [FILENAME] -o OUTPUTFILE Examples: dualhead.py 1024x768-1280x1024 gnomerocks.jpg -o gnomerocks2x.jpg Creates a 2304x1024 image with two scaled copies of gnomerocks.jpg: one positioned at (0x0)-(1024x768), the other at (1024x0)-(2304x1024). dualhead.py 1024x768 gnomerocks.jpg ubunturocks.jpg -o wallpaper.jpg Creates a 2048x768 image with two scaled images: gnomerocks.jpg positioned at (0x0)-(1024x768), ubunturocks.jpg positioned at (1024x0)-(2048x768). """ import re import optparse import Image def parse_resolution(s): """Parse a resolution string. >>> parse_resolution('1024x768') ((1024, 768), (1024, 768)) >>> parse_resolution('1024x768-1280x960') ((1024, 768), (1280, 960)) """ pattern = re.compile(r"^(?P\d+)x(?P

\d+)" r"(?:-(?P\d+)x(?P

\d+))?$") m = pattern.match(s) if not m: raise ValueError("specify resolution as WIDTHxHEIGHT" " or WIDTHxHEIGHT-WIDTHxHEIGHT") w1 = int(m.group('w1')) h1 = int(m.group('h1')) if m.group('w2'): w2 = int(m.group('w2')) h2 = int(m.group('h2')) else: w2, h2 = w1, h1 return (w1, h1), (w2, h2) def make_wallpaper(resolution, left_inputfile, right_inputfile, outputfile): """Create a wallpaper.""" (w1, h1), (w2, h2) = resolution output_size = (w1 + w2), max(h1, h2) left_image = load_and_resize(left_inputfile, (w1, h1)) right_image = load_and_resize(right_inputfile, (w2, h2)) image = Image.new('RGB', output_size) image.paste(left_image, (0, 0)) image.paste(right_image, (w1, 0)) image.save(outputfile) def load_and_resize(filename, size): """Load an image from file, and resize it if necessary.""" image = Image.open(filename) if image.mode != 'RGB': image = image.convert('RGB') if image.size != size: image = image.resize(size, Image.BICUBIC) return image def main(): """Main program.""" parser = optparse.OptionParser("Usage: %prog WxH[-WxH]" " FILENAME [FILENAME] -o OUTPUTFILE", description="Generates wallpapers" " for dual-head desktops.") parser.add_option('--example', help='show usage examples and exit', action='store_true', dest='example', default=False) parser.add_option('-o', metavar='OUTPUTFILE', help='name of the output file (required)', action='store', dest='outputfile', default=None) parser.add_option('--test', help='run unit tests', action='store_true', dest='tests', default=False) opts, args = parser.parse_args() if opts.tests: return test() if opts.example: print __doc__.strip() return if len(args) < 1: parser.error("please specify desired resolution") try: resolution = parse_resolution(args[0]) except ValueError, e: parser.error(str(e)) if len(args) < 2: parser.error("please specify at least one image file name") if len(args) > 3: parser.error("too many file names") if not opts.outputfile: parser.error("please specify the output file name (-o)") if len(args) > 2: left_inputfile = args[1] right_inputfile = args[2] else: left_inputfile = right_inputfile = args[1] make_wallpaper(resolution=resolution, left_inputfile=left_inputfile, right_inputfile=right_inputfile, outputfile=opts.outputfile) def test(): """Run doctests in this module.""" import doctest, unittest suite = doctest.DocTestSuite() unittest.TextTestRunner().run(suite) if __name__ == '__main__': main()