Mercurial > hg > montage
changeset 0:b7348ffe5b46
initial import of montage
author | k0s <k0scist@gmail.com> |
---|---|
date | Mon, 07 Sep 2009 15:38:38 -0400 |
parents | |
children | c5d30bfd032e |
files | example/cycle-wordle.png example/ghostfoxes.png example/tree_sky_pattern.jpg example/wm-background.png montage.ini montage/__init__.py montage/formatters.py montage/utils.py setup.py |
diffstat | 9 files changed, 117 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/montage.ini Mon Sep 07 15:38:38 2009 -0400 @@ -0,0 +1,22 @@ +#!/usr/bin/env paster + +[DEFAULT] +debug = true +email_to = k0scist@gmail.com +smtp_server = localhost +error_email_from = paste@localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 5151 + +[composite:main] +use = egg:Paste#urlmap +/ = decoupage + +set debug = false + +[app:decoupage] +paste.app_factory = decoupage.factory:factory +decoupage.directory = %(here)s/example \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/montage/__init__.py Mon Sep 07 15:38:38 2009 -0400 @@ -0,0 +1,1 @@ +#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/montage/formatters.py Mon Sep 07 15:38:38 2009 -0400 @@ -0,0 +1,11 @@ +from decoupage.formatters import All + +class Montage(All): + + def __init__(self, arg): + # XXX dummy arg + self.match = [ "*.jpg", "*.png", ] + # XXX should really filter on mimetype + + def __call__(self, request, data): + All.__call__(self, request, data)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/montage/utils.py Mon Sep 07 15:38:38 2009 -0400 @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +import os + +from PIL import Image + +def crop_resize(image, size): + """crop out the proportional middle of the image and set to the desired size""" + assert size[0] or size[1] + + size = list(size) + + if size[0] > image.size[0]: + return image + if size[1] > image.size[1]: + return image + + image_ar = image.size[0]/float(image.size[1]) + crop = not size[0] or not size[1] + if not size[1]: + size[1] = int(image.size[1]*size[0]/float(image.size[0]) ) + if not size[0]: + size[0] = int(image.size[0]*size[1]/float(image.size[1]) ) + size_ar = size[0]/float(size[1]) + + if crop: + if image_ar > size_ar: + # trim the width + xoffset = int(0.5*(image.size[0] - size_ar*image.size[1])) + image = image.crop((xoffset, 0, image.size[0]-xoffset, image.size[1])) + elif image_ar < size_ar: + # trim the height + yoffset = int(0.5*(image.size[1] - image.size[0]/size_ar)) + image = image.crop((0, yoffset, image.size[0], image.size[1] - yoffset)) + + return image.resize(size, Image.ANTIALIAS) + +if __name__ == '__main__': + from optparse import OptionParser + parser = OptionParser() + parser.add_option('-f', '--file') + parser.add_option('-W', '--width') + parser.add_option('-H', '--height') + (options, args) = parser.parse_args() + + assert os.path.exists(options.file) + + i = Image.open(options.file) + new_image = crop_resize(i, (int(options.width), int(options.height))) + new_image.show()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setup.py Mon Sep 07 15:38:38 2009 -0400 @@ -0,0 +1,33 @@ +from setuptools import setup, find_packages +import sys, os + +version = '0.0' + +setup(name='montage', + version=version, + description="photogallery using decoupage", + long_description="""\ +""", + classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='photo gallery decoupage', + author='Jeff Hammel', + author_email='k0scist@gmail.com', + url='http://explosivedecompression.net', + license='GPL', + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + include_package_data=True, + zip_safe=False, + install_requires=[ + # -*- Extra requirements: -*- + 'decoupage', + 'PIL' + ], + dependency_links=[ + "http://dist.repoze.org/PIL-1.1.6.tar.gz", + ], + entry_points=""" + # -*- Entry points: -*- + [decoupage.formatters] + montage = montage.formatters:Montage + """, + )