views:

116

answers:

1

hi,

I want to specify a light source at a particular location in an image using Python.

PIL's ImageEnhance module does provide a way to briten an image. but I want to have a control over light source placement to acheieve special effects. Does anyone know how to do this?

thank you!

+1  A: 

So, the bad news is that PIL can't do that. I trhow a couple of ideas bellow, unfortunatelly none of which is straightforward.

GIMP (GNU Image Manipulation Program) does have an awesome "ligthning effects" plug-in,

GIMP is scriptable in Python, and it is possible to call teh plug-in paramtrically. The drawback is that your plug-in has to urn from within GIMP's process. (So you'd either estart GIMP as a batch for a one time run, or have to design a server python plug-in that processes your images through the lightning effects plug-in)

Other optionn I ma familiar with also involves off-process rendering would be use POVRay: render your image as the pigment-map for a 1x1x0.1 plane slab and then you can place "real" light-sources around.

Another way is using OpenGL yourself - I browseddarond a bit, and maybe this "gloss" project can provide a way for you to use light sources without havign to descend into lowlevel opengl: http://www.tuxradar.com/gloss

Or -- "fake" it with a rectangular grid of black and white rectangles that you combine with your through color multiplication. This is the only way that would allow yiou to keep with PIL alone, but the "grid" lines are too visible, and I think that trying to smooth with blur would not cut it:

def fake_light(image, tilesize=50):
    WIDTH, HEIGHT = i.size
    for x in xrange(0, WIDTH, tilesize):
        for y in xrange(0, HEIGHT, tilesize):
            br = int(255 * (1 - x / float(WIDTH) * y /float(HEIGHT)))
            tile = Image.new("RGBA", (tilesize, tilesize), (255,255,255,128))
            image.paste((br,br,br), (x, y, x + tilesize, y + tilesize), mask=tile)
jsbueno
Thanks jsbueno! The workarounds you mention are all excellent suggestions. I have done it using OpenGL (pyopenGL) but wanted to know if there is a way in PIL to do this... Thank you once again.
apt