Подтвердить что ты не робот

Как создать круговые миниатюры с PIL?

Как создать пиктограммы круговых изображений с помощью PIL? Пространство вне круга должно быть прозрачным.

Фрагменты будут высоко оценены, спасибо заранее.

4b9b3361

Ответ 1

Самый простой способ сделать это - использовать маски. Создайте черно-белую маску с любой формой, которую вы хотите. И используйте putalpha чтобы поместить эту форму в качестве альфа-слоя:

from PIL import Image, ImageOps

mask = Image.open('mask.png').convert('L')
im = Image.open('image.png')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)

output.save('output.png')

Вот маска, которую я использовал:

alt text


Если вы хотите, чтобы размер миниатюры был переменным, вы можете использовать ImageDraw и нарисовать маску:

from PIL import Image, ImageOps, ImageDraw

size = (128, 128)
mask = Image.new('L', size, 0)
draw = ImageDraw.Draw(mask) 
draw.ellipse((0, 0) + size, fill=255)

im = Image.open('image.jpg')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)

output.save('output.png')

Если вы хотите вывод в GIF, вам нужно использовать функцию вставки вместо putalpha:

from PIL import Image, ImageOps, ImageDraw

size = (128, 128)
mask = Image.new('L', size, 255)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + size, fill=0)

im = Image.open('image.jpg')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.paste(0, mask=mask)
output.convert('P', palette=Image.ADAPTIVE)

output.save('output.gif', transparency=0)

Обратите внимание, что я сделал следующие изменения:

  • Маска теперь перевернута. Белый был заменен на черный и наоборот.
  • Я конвертирую в "P" с "адаптивной" палитрой. В противном случае PIL будет использовать только веб-безопасные цвета, и результат будет выглядеть плохо.
  • Я добавляю информацию прозрачности к изображению.

Обратите внимание: с этим подходом связана большая проблема. Если изображение GIF содержит черные части, все они также станут прозрачными. Вы можете обойти это, выбрав другой цвет для прозрачности. Я настоятельно рекомендую вам использовать формат PNG для этого. Но если ты не можешь, то это лучшее, что ты можешь сделать.

Ответ 2

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

from PIL import Image, ImageOps, ImageDraw

im = Image.open('image.jpg')
bigsize = (im.size[0] * 3, im.size[1] * 3)
mask = Image.new('L', bigsize, 0)
draw = ImageDraw.Draw(mask) 
draw.ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(im.size, Image.ANTIALIAS)
im.putalpha(mask)

это дает гораздо лучший результат, на мой взгляд.