Logo Search packages:      
Sourcecode: rapid-photo-downloader version File versions  Download package

dropshadow.py

#!/usr/bin/python


import StringIO
import gtk
from PIL import Image, ImageFilter

def image_to_pixbuf(image):
    # this one handles transparency, unlike the default example in the pygtk FAQ
    # this is also from the pygtk FAQ
    IS_RGBA = image.mode=='RGBA'
    return gtk.gdk.pixbuf_new_from_data(
            image.tostring(), # data
            gtk.gdk.COLORSPACE_RGB, # color mode
            IS_RGBA, # has alpha
            8, # bits
            image.size[0], # width
            image.size[1], # height
            (IS_RGBA and 4 or 3) * image.size[0] # rowstride
            ) 
    

def image_to_pixbuf_no_transparency(image):
     fd = StringIO.StringIO()
     image.save(fd, "ppm")
     contents = fd.getvalue()
     fd.close()
     loader = gtk.gdk.PixbufLoader("pnm")
     loader.write(contents, len(contents))
     pixbuf = loader.get_pixbuf()
     loader.close()
     return pixbuf
     
def pixbuf_to_image(pb):
    assert(pb.get_colorspace() == gtk.gdk.COLORSPACE_RGB)
    dimensions = pb.get_width(), pb.get_height()
    stride = pb.get_rowstride()
    pixels = pb.get_pixels()
    mode = pb.get_has_alpha() and "RGBA" or "RGB"
    return Image.frombuffer(mode, dimensions, pixels,
                            "raw", mode, stride, 1)


00044 class DropShadow():
    """
    Adds a gaussian blur drop shadow to a PIL image.
    
    Caches backgrounds of particular sizes for improved performance.
    
    Backgrounds can be made transparent.
    
    Modification of code from Kevin Schluff and Matimus
    License: Python license
    See:
    http://code.activestate.com/recipes/474116/ (r2)
    http://bytes.com/topic/python/answers/606952-pil-paste-image-top-other-dropshadow
    
    """
    
00060     def __init__(self, offset=(5,5), background_color=0xffffff, shadow = (0x44, 0x44, 0x44, 0xff), 
                                border=8, iterations=3, trim_border=False):
        """
        offset            - Offset of the shadow from the image as an (x,y) tuple. Can be
                            positive or negative.
        background_color  - Background colour behind the image.
        shadow            - Shadow colour (darkness).
        border            - Width of the border around the image. This must be wide
                            enough to account for the blurring of the shadow.
        trim_border       - If true, the border will only be created on the
                            sides it needs to be (i.e. only on two sides)
        iterations        - Number of times to apply the filter. More iterations 
                            produce a more blurred shadow, but increase processing time.
                                
        To make backgrounds transparent, ensure the alpha value of the shadow color is the 
        same as the background color, e.g. if background_color is 0xffffff, shadow's alpha should be 0xff
        """
        self.backgrounds = {}
        self.offset = offset
        self.background_color = background_color
        self.shadow = shadow
        self.border = border
        self.trim_border = trim_border
        self.iterations = iterations
        
        if self.offset[0] < 0 or not self.trim_border:
            self.left_spacing = self.border
        else:
            self.left_spacing = 0
        
        if self.offset[1] < 0 or not self.trim_border:
            self.top_spacing = self.border
        else:
            self.top_spacing = 0
        
        
00096     def dropShadow(self, image):
        """
        image             - The image to overlay on top of the shadow.
        """
        dimensions = (image.size[0], image.size[1])
        if not dimensions in self.backgrounds:
            
            # Create the backdrop image -- a box in the background colour with a 
            # shadow on it.
            
            if self.trim_border:
                totalWidth = image.size[0] + abs(self.offset[0]) + self.border
                totalHeight = image.size[1] + abs(self.offset[1]) + self.border
            else:
                totalWidth = image.size[0] + abs(self.offset[0]) + 2 * self.border
                totalHeight = image.size[1] + abs(self.offset[1]) + 2 * self.border
                
            back = Image.new("RGBA", (totalWidth, totalHeight), self.background_color)
            
            # Place the shadow, taking into account the offset from the image
            if self.offset[0] > 0 and self.trim_border:
                shadowLeft = max(self.offset[0], 0)
            else:
                shadowLeft = self.border + max(self.offset[0], 0)
            if self.offset[1] > 0 and self.trim_border:
                shadowTop = max(self.offset[1], 0)
            else:
                shadowTop = self.border + max(self.offset[1], 0)
            
            back.paste(self.shadow, [shadowLeft, shadowTop, shadowLeft + image.size[0], 
                shadowTop + image.size[1]] )
            
            # Apply the filter to blur the edges of the shadow.    Since a small kernel
            # is used, the filter must be applied repeatedly to get a decent blur.
            n = 0
            while n < self.iterations:
                back = back.filter(ImageFilter.BLUR)
                n += 1
                
            self.backgrounds[dimensions] = back
        
        # Paste the input image onto the shadow backdrop                
        imageLeft = self.left_spacing - min(self.offset[0], 0)
        imageTop = self.top_spacing - min(self.offset[1], 0)
            
        back = self.backgrounds[dimensions].copy()
        back.paste(image, (imageLeft, imageTop))
    
        return back
        

    
if __name__ == "__main__":
    import sys
    import os
    import common


    # create another file with a drop shadow
    f = sys.argv[1]
    
    image = Image.open(f)
    image.thumbnail((60,36), Image.ANTIALIAS)
    image2 = image.copy()
    
    path, name = os.path.split(f)
    name, ext = os.path.splitext(name)
     
    #image = dropShadow(image, shadow = (0x44, 0x44, 0x44, 0xff))
    dropShadow = DropShadow(offset=(3,3), shadow = (0x34, 0x34, 0x34, 0xff), border=6)
    image = dropShadow.dropShadow(image)
    image2 = dropShadow.dropShadow(image2)
    
    nf = os.path.join(path, "%s_small_shadow%s" % (name, ext))
    nf2 = os.path.join(path, "%s_small_shadow2%s" % (name, ext))
    image.save(nf)
    image2.save(nf2)
    print "wrote %s , %s" % (nf, nf2)
     

Generated by  Doxygen 1.6.0   Back to index