Размытие области в форме скругленного прямоугольника внутри изображения - PullRequest
0 голосов
/ 20 мая 2018

Я хочу размыть прямоугольник (с закругленными углами) на изображении, используя подушку питона.Я уже нашел способ размывать только определенную часть изображения.

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()

Кроме того, я нашел способ добавить закругленные углы на прямоугольник ( Проблемы с прозрачностью при рисовании прямоугольника с закругленными углами )

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

К сожалению, я не могу найти способ объединить эти два исходных кода, чтобы они работали.

Мой пример изображения: example image

1 Ответ

0 голосов
/ 20 мая 2018

Что вам нужно сделать, так это создать маску для 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

Маска:

created mask

Примените маску к своему изображению:

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()

Я изменил некоторые размеры и пути.В вашем коде не было импорта, я завершил его до минимально проверяемого завершенного примера .

Resulting Image, reduzed in size

...