模糊图像内部形状像圆角矩形的区域

时间:2021-04-16 00:25:25

I want to blur a rectangle (with rounded corners) in an image using python pillow. I already found a way to blur only a certain part of a picture.

我想使用python枕头在图像中模糊一个矩形(带圆角)。我已经找到了一种模糊图片某个部分的方法。

img = Image.open('assets/images/image.png')
x, y = 300, 1600

cropped_img = img.crop((x, y, 1000, 2600))

blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(20))

img.paste(blurred_img, (x, y))

img.save('assets/images/new.png')
img.show()

Furthermore I found a method to add rounded corners on a rectangle(Transparency issues drawing a rectangle with rounded corners)

此外,我找到了一种在矩形上添加圆角的方法(透明度问题绘制一个带圆角的矩形)

def round_corner(radius):
   corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0))
   draw = ImageDraw.Draw(corner)
   draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270)
   return corner

def round_rectangle(rectangle, radius):
   corner = round_corner(radius)
   rectangle.paste(corner, (0, 0))
   rectangle.paste(corner.rotate(90), (0, rectangle.size[1] - radius))
   rectangle.paste(corner.rotate(180), (rectangle.size[0] - radius,   rectangle.size[1] - radius))
   rectangle.paste(corner.rotate(270), (rectangle.size[0] - radius, 0))
   return rectangle

Unfortunately, I can't find a way to combine these two source codes so that they work.

不幸的是,我找不到一种方法来组合这两个源代码,以便它们工作。

My Example Image:模糊图像内部形状像圆角矩形的区域

我的示例图片:

1 个解决方案

#1


3  

What you need to do, is essentially to create a mask for the Image.paste() that only pastes those parts of the blurred image that lie inside the rounded rectangle.

你需要做的,主要是为Image.paste()创建一个遮罩,它只粘贴位于圆角矩形内的模糊图像的那些部分。

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

# when using an image as mask only the alpha channel is important
solid_fill =  (50,50,50,255) 


def create_rounded_rectangle_mask(rectangle, radius):
    # create mask image. all pixels set to translucent
    i = Image.new("RGBA",rectangle.size,(0,0,0,0))

    # create corner
    corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0))
    draw = ImageDraw.Draw(corner)
    # added the fill = .. you only drew a line, no fill
    draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill = solid_fill)

    # max_x, max_y
    mx,my = rectangle.size

    # paste corner rotated as needed
    # use corners alpha channel as mask

    i.paste(corner, (0, 0), corner)
    i.paste(corner.rotate(90), (0, my - radius),corner.rotate(90))
    i.paste(corner.rotate(180), (mx - radius,   my - radius),corner.rotate(180))
    i.paste(corner.rotate(270), (mx - radius, 0),corner.rotate(270))

    # draw both inner rects
    draw = ImageDraw.Draw(i)
    draw.rectangle( [(radius,0),(mx-radius,my)],fill=solid_fill)
    draw.rectangle( [(0,radius),(mx,my-radius)],fill=solid_fill)

    return i

Mask:

模糊图像内部形状像圆角矩形的区域

Apply the mask to your image:

将蒙版应用于图像:

img = Image.open('pic.jpg')

x, y = 300, 160 
radius = 75

cropped_img = img.crop((x, y, 600, 600))

# the filter removes the alpha, you need to add it again by converting to RGBA
blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(20),).convert("RGBA")

# paste blurred, uses alphachannel of create_rounded_rectangle_mask() as mask 
# only those parts of the mask that have a non-zero alpha gets pasted
img.paste(blurred_img, (x, y), create_rounded_rectangle_mask(cropped_img,radius))

img.save('new2.png')
img.show()

I changed some dimensions and paths. Your code lacked the imports, I completed it to a minimal verifyable complete example.

我改变了一些尺寸和路径。您的代码缺少导入,我将其完成为最小可验证的完整示例。

模糊图像内部形状像圆角矩形的区域

#1


3  

What you need to do, is essentially to create a mask for the Image.paste() that only pastes those parts of the blurred image that lie inside the rounded rectangle.

你需要做的,主要是为Image.paste()创建一个遮罩,它只粘贴位于圆角矩形内的模糊图像的那些部分。

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

# when using an image as mask only the alpha channel is important
solid_fill =  (50,50,50,255) 


def create_rounded_rectangle_mask(rectangle, radius):
    # create mask image. all pixels set to translucent
    i = Image.new("RGBA",rectangle.size,(0,0,0,0))

    # create corner
    corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0))
    draw = ImageDraw.Draw(corner)
    # added the fill = .. you only drew a line, no fill
    draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill = solid_fill)

    # max_x, max_y
    mx,my = rectangle.size

    # paste corner rotated as needed
    # use corners alpha channel as mask

    i.paste(corner, (0, 0), corner)
    i.paste(corner.rotate(90), (0, my - radius),corner.rotate(90))
    i.paste(corner.rotate(180), (mx - radius,   my - radius),corner.rotate(180))
    i.paste(corner.rotate(270), (mx - radius, 0),corner.rotate(270))

    # draw both inner rects
    draw = ImageDraw.Draw(i)
    draw.rectangle( [(radius,0),(mx-radius,my)],fill=solid_fill)
    draw.rectangle( [(0,radius),(mx,my-radius)],fill=solid_fill)

    return i

Mask:

模糊图像内部形状像圆角矩形的区域

Apply the mask to your image:

将蒙版应用于图像:

img = Image.open('pic.jpg')

x, y = 300, 160 
radius = 75

cropped_img = img.crop((x, y, 600, 600))

# the filter removes the alpha, you need to add it again by converting to RGBA
blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(20),).convert("RGBA")

# paste blurred, uses alphachannel of create_rounded_rectangle_mask() as mask 
# only those parts of the mask that have a non-zero alpha gets pasted
img.paste(blurred_img, (x, y), create_rounded_rectangle_mask(cropped_img,radius))

img.save('new2.png')
img.show()

I changed some dimensions and paths. Your code lacked the imports, I completed it to a minimal verifyable complete example.

我改变了一些尺寸和路径。您的代码缺少导入,我将其完成为最小可验证的完整示例。

模糊图像内部形状像圆角矩形的区域