как закруглить логотип без белого фона(прозрачный?) с помощью пил?

Я получил квадратный логотип, и мне нужно round_corner его, искал некоторое время и получил следующий код "работает":

def round_corner_jpg(image, radius):
    """generate round corner for image"""
    mask = Image.new('RGB', image.size)
    #mask = Image.new('RGB', (image.size[0] - radius, image.size[1] - radius))
    #mask = Image.new('L', image.size, 255)
    draw = aggdraw.Draw(mask)
    brush = aggdraw.Brush('black')
    width, height = mask.size
    draw.rectangle((0,0,width,height), aggdraw.Brush('white'))
    #upper-left corner
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush)
    #upper-right corner
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush)
    #bottom-left corner
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush)
    #bottom-right corner
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush)
    #center rectangle
    draw.rectangle((radius, radius, width - radius, height - radius), brush)
    #four edge rectangle
    draw.rectangle((radius, 0, width - radius, radius), brush)
    draw.rectangle((0, radius, radius, height-radius), brush)
    draw.rectangle((radius, height-radius, width-radius, height), brush)
    draw.rectangle((width-radius, radius, width, height-radius), brush)
    draw.flush()
    del draw
    return ImageChops.add(mask, image)

затем я сохранил возвращенный объект изображения, однако он имеет белый фон в углу такой Как я могу избавиться от белого фона или сделать его невидимым? Заранее спасибо~

изменить: вот код от fraxel, спасибо~

def add_corners(im, rad):
    circle = Image.new('L', (rad * 2, rad * 2), 0)
    draw = ImageDraw.Draw(circle)
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)
    alpha = Image.new('L', im.size, "white")
    w, h = im.size
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
    im.putalpha(alpha)
    return im


if __name__ == '__main__':
    im = Image.open('1.jpg')
    im = add_corners(im, 100)
    im.save('out.png')`

мне очень жаль..Мне нужно, чтобы форма изображения была эллипсом, а не прямоугольником, т. е. списать материал с картинки, и @fraxel, я все еще вижу белый угол на картинке, которую вы обработали для меня

2 ответов


во-первых, убедитесь, что вы сохраняете изображение в формате, который поддерживает прозрачность. PNG так, JPG нет... Ниже приведен довольно приятный код, который добавит прозрачные углы. Он работает следующим образом:

  1. рисует круг с радиусом, rad, используя draw.ellipse()
  2. создайте изображение для альфа-канала того же размера, что и ваше изображение
  3. Чоп наш круг на четыре части (закругленные углы), и поместите их в правильные углы Альфа-образ
  4. поместите альфа-канал в изображение с помощью putalpha()
  5. Сохранить как png, таким образом, сохраняя прозрачность.

вот код:

import Image, ImageDraw

def add_corners(im, rad):
    circle = Image.new('L', (rad * 2, rad * 2), 0)
    draw = ImageDraw.Draw(circle)
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)
    alpha = Image.new('L', im.size, 255)
    w, h = im.size
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
    im.putalpha(alpha)
    return im

im = Image.open('tiger.jpg')
im = add_corners(im, 100)
im.save('tiger.png')

пример изогнутого края тигра:

enter image description here

вот ваше изображение, обработанное этим кодом, дающим прозрачные углы:

enter image description here


вы пробовали что-то вроде image.putalpha(mask) заменить альфа-канал изображения на маску? Кажется, он должен делать то, что ты хочешь. mask возможно, нужно быть в режиме "L", чтобы это работало правильно, и image должен быть "RGBA", но может быть автоматически преобразован для вас.

верхний ответ здесь дает несколько хороших примеров: Как создать круговые эскизы с помощью PIL?

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

как только у вас есть это изображение, вы можете заменить return ImageChops.add(mask, image) by image.putalpha(mask); return image и это должно привести к тому, что изображение будет прозрачным только в черных областях маски.

вам может потребоваться сначала преобразовать изображение с помощью image.convert('RGBA') но я думаю, что это не нужно в более поздних версиях пил, он делает это автоматически.

что-то вроде: (К сожалению не могу проверить это прямо сейчас)

def round_corner_jpg(image, radius):
    """generate round corner for image"""
    mask = Image.new('L', image.size) # filled with black by default
    draw = aggdraw.Draw(mask)
    brush = aggdraw.Brush('white')
    width, height = mask.size
    #upper-left corner
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush)
    #upper-right corner
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush)
    #bottom-left corner
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush)
    #bottom-right corner
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush)
    #center rectangle
    draw.rectangle((radius, radius, width - radius, height - radius), brush)
    #four edge rectangle
    draw.rectangle((radius, 0, width - radius, radius), brush)
    draw.rectangle((0, radius, radius, height-radius), brush)
    draw.rectangle((radius, height-radius, width-radius, height), brush)
    draw.rectangle((width-radius, radius, width, height-radius), brush)
    draw.flush()
    image = image.convert('RGBA')
    image.putalpha(mask)
    return image