All pastes #473124 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-05-06 01:45 UTC
rendered paste body
#!/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<w1>\d+)x(?P<h1>\d+)"
                         r"(?:-(?P<w2>\d+)x(?P<h2>\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()