如何使用 Python PIL 模糊图像的非矩形或圆形区域?
How to blur non-rectangular or circular area of image with Python PIL?
在 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 个矩形。这样做会减慢我的代码速度,但我会采取任何我能得到的解决方案。)
我理解 this can be done with Numpy,但我更愿意使用 PIL,因为此脚本中的所有其他内容都已使用 PIL 编码。
看看这个例子(rounded_rectangle 来自 here 的函数):
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)。
在 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 个矩形。这样做会减慢我的代码速度,但我会采取任何我能得到的解决方案。)
我理解 this can be done with Numpy,但我更愿意使用 PIL,因为此脚本中的所有其他内容都已使用 PIL 编码。
看看这个例子(rounded_rectangle 来自 here 的函数):
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)。