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