简体   繁体   English

如何使用Python PIL模糊非矩形或圆形图像区域?

[英]How to blur non-rectangular or circular area of image with Python PIL?

Using PIL in Python, I am superimposing a PNG image on top of another, larger image. 在Python中使用PIL,我将PNG图像叠加在另一个更大的图像上。 The smaller image is semi-transparent. 较小的图像是半透明的。

I would like for the area behind the smaller image to be blurred on the larger image. 我希望较小图像背后的区域在较大的图像上模糊。 The following code blurs a rectangular area: 以下代码模糊了一个矩形区域:

box = (3270, 1150, 4030, 2250)      # (x1, y1, x2, y2)
ic = outputImage.crop(box)
ic = ic.filter(ImageFilter.BoxBlur(20))
outputImage.paste(ic, box)

However, I need to blur a rectangular area that has rounded corners . 但是,我需要模糊一个有圆角的矩形区域。

This is what the superimposed image looks like: 这就是叠加图像的样子:

So, is it possible to define a custom shape for a cropped area in PIL? 那么,是否可以为PIL中的裁剪区域定义自定义形状?

If not, is it possible to at least crop circle-shaped areas? 如果没有,是否有可能至少裁剪圆形区域? (For full coverage and without any overhang, my area would have to broken down into 6 sub-areas: 4 circles and 2 rectangles. Doing all this will slow down my code, but I will take whatever solution I can get.) (对于完全覆盖并且没有任何悬垂,我的区域将不得不分解为6个子区域:4个圆圈和2个矩形。完成所有这些将减慢我的代码,但我会采取任何我能得到的解决方案。)

I understand that this can be done with Numpy , but I would prefer to use PIL because everything else in this script is already coded with PIL. 我知道这可以用Numpy来完成 ,但是我更喜欢使用PIL,因为这个脚本中的其他内容都已经用PIL编码了。

Take a look at this example (rounded_rectangle function from here ): 看一下这个例子( 这里的 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)

Input image: 输入图片:

可乐在海滩上(在乌克兰)

Mask: 面具:

与圆角落的白色长方形在黑背景

Output image: 输出图像:

被弄脏的罐头在海滩的可乐

Tested with Python 2.7.12 and Pillow 3.1.2 (it doesn't have BoxBlur). 用Python 2.7.12和Pillow 3.1.2测试(它没有BoxBlur)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM