Mercurial > public > madeira
comparison photologue/utils/reflection.py @ 71:e2868ad47a1e
For Django 1.4, using the new manage.py.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 14 Apr 2012 16:40:29 -0500 |
parents | madeira/photologue/utils/reflection.py@63e4211628e1 |
children |
comparison
equal
deleted
inserted
replaced
70:f26cdda0ad8b | 71:e2868ad47a1e |
---|---|
1 """ Function for generating web 2.0 style image reflection effects. | |
2 | |
3 Copyright (c) 2007, Justin C. Driscoll | |
4 All rights reserved. | |
5 | |
6 Redistribution and use in source and binary forms, with or without modification, | |
7 are permitted provided that the following conditions are met: | |
8 | |
9 1. Redistributions of source code must retain the above copyright notice, | |
10 this list of conditions and the following disclaimer. | |
11 | |
12 2. Redistributions in binary form must reproduce the above copyright | |
13 notice, this list of conditions and the following disclaimer in the | |
14 documentation and/or other materials provided with the distribution. | |
15 | |
16 3. Neither the name of reflection.py nor the names of its contributors may be used | |
17 to endorse or promote products derived from this software without | |
18 specific prior written permission. | |
19 | |
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
24 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
27 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 | |
31 """ | |
32 | |
33 try: | |
34 import Image | |
35 import ImageColor | |
36 except ImportError: | |
37 try: | |
38 from PIL import Image | |
39 from PIL import ImageColor | |
40 except ImportError: | |
41 raise ImportError("The Python Imaging Library was not found.") | |
42 | |
43 | |
44 def add_reflection(im, bgcolor="#00000", amount=0.4, opacity=0.6): | |
45 """ Returns the supplied PIL Image (im) with a reflection effect | |
46 | |
47 bgcolor The background color of the reflection gradient | |
48 amount The height of the reflection as a percentage of the orignal image | |
49 opacity The initial opacity of the reflection gradient | |
50 | |
51 Originally written for the Photologue image management system for Django | |
52 and Based on the original concept by Bernd Schlapsi | |
53 | |
54 """ | |
55 # convert bgcolor string to rgb value | |
56 background_color = ImageColor.getrgb(bgcolor) | |
57 | |
58 # copy orignial image and flip the orientation | |
59 reflection = im.copy().transpose(Image.FLIP_TOP_BOTTOM) | |
60 | |
61 # create a new image filled with the bgcolor the same size | |
62 background = Image.new("RGB", im.size, background_color) | |
63 | |
64 # calculate our alpha mask | |
65 start = int(255 - (255 * opacity)) # The start of our gradient | |
66 steps = int(255 * amount) # the number of intermedite values | |
67 increment = (255 - start) / float(steps) | |
68 mask = Image.new('L', (1, 255)) | |
69 for y in range(255): | |
70 if y < steps: | |
71 val = int(y * increment + start) | |
72 else: | |
73 val = 255 | |
74 mask.putpixel((0, y), val) | |
75 alpha_mask = mask.resize(im.size) | |
76 | |
77 # merge the reflection onto our background color using the alpha mask | |
78 reflection = Image.composite(background, reflection, alpha_mask) | |
79 | |
80 # crop the reflection | |
81 reflection_height = int(im.size[1] * amount) | |
82 reflection = reflection.crop((0, 0, im.size[0], reflection_height)) | |
83 | |
84 # create new image sized to hold both the original image and the reflection | |
85 composite = Image.new("RGB", (im.size[0], im.size[1]+reflection_height), background_color) | |
86 | |
87 # paste the orignal image and the reflection into the composite image | |
88 composite.paste(im, (0, 0)) | |
89 composite.paste(reflection, (0, im.size[1])) | |
90 | |
91 # return the image complete with reflection effect | |
92 return composite | |
93 |