Skip to content

Instantly share code, notes, and snippets.

@tai2
Created January 26, 2013 01:00
Show Gist options
  • Save tai2/4639341 to your computer and use it in GitHub Desktop.
Save tai2/4639341 to your computer and use it in GitHub Desktop.
drop shadow using gaussian filter(very slow)
import sys
import os
import math
import Image
def make_filter_kernel(size, sigma_sq):
s = 0.0
half = size / 2
f_min = -(size / 2)
f_ub = size / 2 + 1
kernel = [[0 for x in range(size)] for y in range(size)]
for y in range(f_min, f_ub):
for x in range(f_min, f_ub):
w = math.exp(-(x * x + y * y) / (2.0 * sigma_sq))
kernel[half + y][half + x] = w
s += w
for y in range(size):
for x in range(size):
kernel[y][x] /= s
return kernel
def render_filter_kernel(kernel, size):
im = Image.new('L', (size, size), 0)
max_val = max([max(l) for l in kernel])
buf = im.load()
for y in range(size):
for x in range(size):
buf[x, y] = 255.0 * kernel[y][x] / max_val
im.save('kernel.png')
def blur_image(im, filter_size, sigma_sq, rect):
filter_mergin = filter_size / 2
reduce_size = (-2 * filter_mergin, -2 * filter_mergin)
new_size = map(sum, zip(im.size, reduce_size))
new_im = Image.new('RGBA', new_size, 0x00000000)
kernel = make_filter_kernel(filter_size, sigma_sq)
render_filter_kernel(kernel, filter_size)
src = im.load()
dst = new_im.load()
for y in range(new_size[1]):
for x in range(new_size[0]):
if rect[0] <= x < rect[2] and rect[1] <= y < rect[3]:
continue
r, g, b = (0.0, 0.0, 0.0)
for fy in range(filter_size):
for fx in range(filter_size):
w = kernel[fy][fx]
sr, sg, sb, sa = src[x + fx, y + fy]
r += w * sr
g += w * sg
b += w * sb
dst[x,y] = (sa<<24) | (int(b)<<16) | (int(g)<<8) | (int(r)<<0)
print '\033[2K\033[30D%3.2f percent processed'%(float(y * new_size[1] + x) * 100 / (new_size[0] * new_size[1])),
sys.stdout.flush()
return new_im
def create_shadow_image(image_size, offset, filter_size, sigma_sq, color):
assert filter_size % 2 == 1
mergin = (filter_size / 2, filter_size / 2)
new_size = map(sum, zip(image_size, offset, mergin, mergin, mergin))
im = Image.new('RGBA', new_size, 0xFFFFFFFF)
buf = im.load()
for y in range(image_size[1]):
for x in range(image_size[0]):
buf[x + offset[0] + mergin[0], y + offset[1] + mergin[1]] = color
rect = (0, 0, image_size[0], image_size[1])
return blur_image(im, filter_size, sigma_sq, rect)
def draw_shadowed_image(filename):
OFFSET = (5, 5)
FILTER_SIZE = 41
SHADOW_COLOR = 0xFF404040
SIGMA_SQ = 100
im = Image.open(filename)
new_im = create_shadow_image(im.size, OFFSET, FILTER_SIZE, SIGMA_SQ, SHADOW_COLOR)
new_im.paste(im, (0, 0) + im.size)
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