Question

Comment générer des vignettes d'images circulaires en utilisant PIL? L'espace extérieur du cercle doit être transparent.

Snippets serait très appréciée, merci d'avance.

Était-ce utile?

La solution

La meilleure façon de le faire est à l'aide de masques. Créer un masque noir et blanc avec la forme que vous voulez. En utilisant putalpha de mettre cette forme en tant que couche 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')

Voici le masque je:

text alt


Si vous voulez que la taille de la vignette pour être variable, vous pouvez utiliser ImageDraw et dessiner le masque:

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

Si vous voulez que la sortie au format GIF, alors vous devez utiliser la fonction de coller au lieu 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)

Notez que je l'ai fait les modifications suivantes:

  • Le masque est maintenant inversée. Le blanc a été remplacé par le noir et vice-versa.
  • je convertir en « P » avec une palette « adaptative ». Dans le cas contraire, PIL utilisera uniquement des couleurs Web sécurisées et le résultat sera mauvais.
  • J'ajoute informations transparence à l'image.

S'il vous plaît noter : Il y a un gros problème avec cette approche. Si l'image GIF contenait des parties noires, tous deviendront transparents aussi bien. Vous pouvez contourner ce problème en choisissant une autre couleur pour la transparence. Je vous conseille vivement d'utiliser le format PNG pour cela. Mais si vous ne pouvez pas alors c'est le meilleur que vous pourriez faire.

Autres conseils

Je voudrais ajouter à la réponse déjà accepté une solution à anticrénelage le cercle obtenu, l'astuce consiste à produire un plus grand masque puis l'échelle vers le bas à l'aide d'un filtre ANTIALIAS: voici le code

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)

Cela produit un résultat beaucoup mieux à mon avis.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top