Last active
December 14, 2015 01:39
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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