2009-05-20 6 views

ответ

62

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

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 для этого. Но если вы не можете, то это лучшее, что вы могли бы сделать.

+0

Отлично! А как насчет вывода gif вместо png? Я думаю, gif не обрабатывает альфу, не так ли? – ohnoes

+0

Gif не поддерживает прозрачность альфа-канала. Он поддерживает только один цвет как прозрачный. Однако я сделал необходимую корректировку для вывода результата в gif. –

+0

отличный ответ. в то время как я могу легко применить эту технику к сохраненным изображениям, я столкнулся с проблемой, применяющей маску внутри python. любой шанс вы могли бы взглянуть на этот вопрос: http://stackoverflow.com/questions/20150552/modify-the-alpha-channel-of-an-image-as-part-of-an-image-processing-workflow – zach

19

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

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) 

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

+1

Чувак, АНТИАЛИАС сделал огромную разницу! Благодаря! = D – ademarizu

+0

Это работало для меня так хорошо. Не нужно создавать маску. –