bgneal@1: """ Function for generating web 2.0 style image reflection effects. bgneal@1: bgneal@1: Copyright (c) 2007, Justin C. Driscoll bgneal@1: All rights reserved. bgneal@1: bgneal@1: Redistribution and use in source and binary forms, with or without modification, bgneal@1: are permitted provided that the following conditions are met: bgneal@1: bgneal@1: 1. Redistributions of source code must retain the above copyright notice, bgneal@1: this list of conditions and the following disclaimer. bgneal@1: bgneal@1: 2. Redistributions in binary form must reproduce the above copyright bgneal@1: notice, this list of conditions and the following disclaimer in the bgneal@1: documentation and/or other materials provided with the distribution. bgneal@1: bgneal@1: 3. Neither the name of reflection.py nor the names of its contributors may be used bgneal@1: to endorse or promote products derived from this software without bgneal@1: specific prior written permission. bgneal@1: bgneal@1: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND bgneal@1: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED bgneal@1: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE bgneal@1: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR bgneal@1: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES bgneal@1: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; bgneal@1: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON bgneal@1: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT bgneal@1: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS bgneal@1: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bgneal@1: bgneal@1: """ bgneal@1: bgneal@1: try: bgneal@1: import Image bgneal@1: import ImageColor bgneal@1: except ImportError: bgneal@1: try: bgneal@1: from PIL import Image bgneal@1: from PIL import ImageColor bgneal@1: except ImportError: bgneal@1: raise ImportError("The Python Imaging Library was not found.") bgneal@1: bgneal@1: bgneal@1: def add_reflection(im, bgcolor="#00000", amount=0.4, opacity=0.6): bgneal@1: """ Returns the supplied PIL Image (im) with a reflection effect bgneal@1: bgneal@1: bgcolor The background color of the reflection gradient bgneal@1: amount The height of the reflection as a percentage of the orignal image bgneal@1: opacity The initial opacity of the reflection gradient bgneal@1: bgneal@1: Originally written for the Photologue image management system for Django bgneal@1: and Based on the original concept by Bernd Schlapsi bgneal@1: bgneal@1: """ bgneal@1: # convert bgcolor string to rgb value bgneal@1: background_color = ImageColor.getrgb(bgcolor) bgneal@1: bgneal@1: # copy orignial image and flip the orientation bgneal@1: reflection = im.copy().transpose(Image.FLIP_TOP_BOTTOM) bgneal@1: bgneal@1: # create a new image filled with the bgcolor the same size bgneal@1: background = Image.new("RGB", im.size, background_color) bgneal@1: bgneal@1: # calculate our alpha mask bgneal@1: start = int(255 - (255 * opacity)) # The start of our gradient bgneal@1: steps = int(255 * amount) # the number of intermedite values bgneal@1: increment = (255 - start) / float(steps) bgneal@1: mask = Image.new('L', (1, 255)) bgneal@1: for y in range(255): bgneal@1: if y < steps: bgneal@1: val = int(y * increment + start) bgneal@1: else: bgneal@1: val = 255 bgneal@1: mask.putpixel((0, y), val) bgneal@1: alpha_mask = mask.resize(im.size) bgneal@1: bgneal@1: # merge the reflection onto our background color using the alpha mask bgneal@1: reflection = Image.composite(background, reflection, alpha_mask) bgneal@1: bgneal@1: # crop the reflection bgneal@1: reflection_height = int(im.size[1] * amount) bgneal@1: reflection = reflection.crop((0, 0, im.size[0], reflection_height)) bgneal@1: bgneal@1: # create new image sized to hold both the original image and the reflection bgneal@1: composite = Image.new("RGB", (im.size[0], im.size[1]+reflection_height), background_color) bgneal@1: bgneal@1: # paste the orignal image and the reflection into the composite image bgneal@1: composite.paste(im, (0, 0)) bgneal@1: composite.paste(reflection, (0, im.size[1])) bgneal@1: bgneal@1: # return the image complete with reflection effect bgneal@1: return composite bgneal@1: