Как создать круглые миниатюры с помощью PIL? - PullRequest
39 голосов
/ 21 мая 2009

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

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

Ответы [ 2 ]

71 голосов
/ 21 мая 2009

Самый простой способ сделать это - использовать маски. Создайте черно-белую маску с любой формой, которую вы хотите. И используйте 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 для этого. Но если ты не можешь, то это лучшее, что ты можешь сделать.

28 голосов
/ 12 марта 2014

Я хотел бы добавить к уже принятому ответу решение сглаживания получающегося круга, задача состоит в том, чтобы создать маску большего размера и затем уменьшить ее, используя фильтр 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)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...