Pergunta

Como faço para gerar miniaturas de imagens circulares usando PIL? O espaço fora do círculo deve ser transparente.

Snippets seria muito apreciada, obrigado antecipadamente.

Foi útil?

Solução

A maneira mais fácil de fazer isso é usando máscaras. Criar uma máscara preta e branca, com qualquer forma que você quiser. E uso putalpha para colocar essa forma como uma camada alpha:

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

Aqui é a máscara que eu usei:

text alt


Se você quer o tamanho da miniatura para ser variável que você pode usar ImageDraw e tirar a máscara:

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

Se você quiser a saída em GIF, então você precisa usar a função colar em vez de 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)

Note que eu fiz as seguintes alterações:

  • A máscara é agora invertido. O branco foi substituído com preto e vice-versa.
  • Eu estou convertendo em 'P' com uma paleta 'adaptativa'. Caso contrário, PIL só vai usar cores web-safe eo resultado vai ficar mal.
  • eu estou adicionando informações de transparência para a imagem.

Por favor nota : Existe um grande problema com esta abordagem. Se a imagem GIF continha peças pretas, todas elas se tornarão transparentes também. Você pode contornar isso escolhendo uma outra cor para a transparência. Eu recomendo fortemente que você use o formato PNG para isso. Mas se você não pode, então, que é o melhor que podia fazer.

Outras dicas

Eu gostaria de adicionar à resposta já aceitou uma solução para antialias o círculo resultante, o truque é produzir uma máscara maior e, em seguida, escalá-lo para baixo, usando um filtro AntiAlias: aqui está o código

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)

Isso produz um resultado muito melhor na minha opinião.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top