如何使用Python PIL对图像中的非矩形或圆形区域进行模糊处理?

4
使用Python中的PIL库,我正在将一个PNG格式的图像叠加在另一张更大的图像上。小图像是半透明的。 我希望在大图像上小图像的背后区域被模糊化。下面的代码可以模糊化一个矩形区域:
box = (3270, 1150, 4030, 2250)      # (x1, y1, x2, y2)
ic = outputImage.crop(box)
ic = ic.filter(ImageFilter.BoxBlur(20))
outputImage.paste(ic, box)

然而,我需要模糊一个带有圆角的矩形区域。
这是叠加图像的样子:

那么,在PIL中是否可以定义裁剪区域的自定义形状?

如果不行,那么至少可以裁剪圆形区域吗?(为了完全覆盖并且没有任何悬挂,我的区域必须分成6个子区域:4个圆形和2个矩形。这样做会减慢我的代码,但我会接受任何可用的解决方案。)

我知道可以使用Numpy来实现这一点,但我更愿意使用PIL,因为此脚本中的其他所有内容都已经使用PIL编码。

1个回答

5

看一下这个例子(来自这里的rounded_rectangle函数):

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFilter

def rounded_rectangle(draw, xy, rad, fill=None):
    x0, y0, x1, y1 = xy
    draw.rectangle([ (x0, y0 + rad), (x1, y1 - rad) ], fill=fill)
    draw.rectangle([ (x0 + rad, y0), (x1 - rad, y1) ], fill=fill)
    draw.pieslice([ (x0, y0), (x0 + rad * 2, y0 + rad * 2) ], 180, 270, fill=fill)
    draw.pieslice([ (x1 - rad * 2, y1 - rad * 2), (x1, y1) ], 0, 90, fill=fill)
    draw.pieslice([ (x0, y1 - rad * 2), (x0 + rad * 2, y1) ], 90, 180, fill=fill)
    draw.pieslice([ (x1 - rad * 2, y0), (x1, y0 + rad * 2) ], 270, 360, fill=fill)

# Open an image
im = Image.open(INPUT_IMAGE_FILENAME)

# Create rounded rectangle mask
mask = Image.new('L', im.size, 0)
draw = ImageDraw.Draw(mask)
rounded_rectangle(draw, (im.size[0]//4, im.size[1]//4, im.size[0]//4*3, im.size[1]//4*3), rad=40, fill=255)
mask.save('mask.png')

# Blur image
blurred = im.filter(ImageFilter.GaussianBlur(20))

# Paste blurred region and save result
im.paste(blurred, mask=mask)
im.save(OUTPUT_IMAGE_FILENAME)

输入图像:

在乌克兰海滩上的可口可乐罐

遮罩:

黑色背景上的白色圆角矩形

输出图像:

模糊的可口可乐罐在海滩上

使用Python 2.7.12和Pillow 3.1.2进行测试(它没有BoxBlur)。


太棒了。它完美地工作。我希望我能给你的点赞多于一次。非常感谢,Andriy! - Crickets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接