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()