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
Binary file example/cycle-wordle.png has changed
Binary file example/ghostfoxes.png has changed
Binary file example/tree_sky_pattern.jpg has changed
Binary file example/wm-background.png has changed
--- /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
+      """,
+      )