Skip to content

Instantly share code, notes, and snippets.

@tai2
Last active December 14, 2015 01:39
Show Gist options
  • Save tai2/5007892 to your computer and use it in GitHub Desktop.
Save tai2/5007892 to your computer and use it in GitHub Desktop.
Drop shadow using distans from edge. This method is fast because shadow area is filled by one pass and flexible because attenuation can be represented by a function of distance from edge.
import sys
import os
import math
import Image
def create_shadow_image(image_size, shadow_size):
mergin = (shadow_size, shadow_size)
new_size = map(sum, zip(image_size, mergin, mergin))
im = Image.new('RGBA', new_size, 0xFFFFFFFF)
buf = im.load()
for y in range(new_size[1]):
for x in range(new_size[0]):
if y < shadow_size:
if x < shadow_size:
# upper left
d = (shadow_size - x) ** 2 + (shadow_size - y) ** 2
elif x < image_size[0] + shadow_size:
# upper center
d = (shadow_size - y) ** 2
else:
# upper right
d = (x - image_size[0] - shadow_size) ** 2 + (shadow_size - y) ** 2
elif y < image_size[1] + shadow_size:
if x < shadow_size:
# center left
d = (shadow_size - x) ** 2
elif x < image_size[0] + shadow_size:
# center center
d = 0
else:
# center right
d = (x - image_size[0] - shadow_size) ** 2
else:
if x < shadow_size:
# bottom left
d = (shadow_size - x) ** 2 + (y - image_size[1] - shadow_size) ** 2
elif x < image_size[0] + shadow_size:
# bottom center
d = (y - image_size[1] - shadow_size) ** 2
else:
# bottom right
d = (x - image_size[0] - shadow_size) ** 2 + (y - image_size[1] - shadow_size) ** 2
t = math.sqrt(d) / math.sqrt(2 * shadow_size ** 2)
v = int(255 * (1 - (1 - t) ** 3))
buf[x, y] = (v, v, v, 128)
sys.stdout.flush()
return im
def draw_shadowed_image(filename):
SHADOW_SIZE = 30
im = Image.open(filename)
new_im = create_shadow_image(im.size, SHADOW_SIZE)
offset = (SHADOW_SIZE,) * 4
base = (0, 0) + im.size
new_im.paste(im, map(sum, zip(base, offset)))
root, ext = os.path.splitext(filename)
new_im.save(root + '_shadowed' + ext)
if __name__ == '__main__':
if len(sys.argv) < 2:
sys.stderr.write('filename please!\n')
sys.exit(1)
draw_shadowed_image(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment