2009-05-20 10 views

Répondre

62

La façon la plus simple de le faire est d'utiliser des masques. Créez un masque noir et blanc avec la forme que vous voulez. Et mettre cette forme comme une 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

alt text


Si vous voulez que la taille des vignettes pour être variable que vous pouvez utiliser le ImageDraw et d'en tirer la 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é. Le blanc a été remplacé par le noir et vis versa.
  • Je convertis en 'P' avec une palette 'adaptative'. Sinon, PIL n'utilisera que des couleurs Web-safe et le résultat sera mauvais.
  • J'ajoute info transparence à l'image

S'il vous plaît noter: Il y a un gros problème avec cette approche. Si l'image gif contient des parties noires, elles deviendront toutes transparentes. Vous pouvez contourner ce problème en choisissant une autre couleur pour la transparence. Je vous conseille fortement d'utiliser le format PNG pour cela. Mais si vous ne pouvez pas alors c'est le mieux que vous puissiez faire.

+0

Parfait! Et que diriez-vous de sortir gif au lieu de png? Je suppose que gif ne gère pas l'alpha, n'est-ce pas? – ohnoes

+0

Gif ne prend pas en charge la transparence du canal alpha. Il prend uniquement en charge la définition d'une couleur comme transparente. Cependant, j'ai fait l'ajustement nécessaire pour sortir le résultat en gif. –

+0

bonne réponse. alors que je peux appliquer cette technique facilement aux images sauvegardées, j'ai rencontré un problème en appliquant le masque dans python. toute chance que vous pourriez jeter un oeil à cette question: http://stackoverflow.com/questions/20150552/modify-the-alpha-channel-of-an-image-as-part-of-an-image-processing-workflow – zach

19

Je voudrais ajouter à la réponse déjà accepté une solution à anticrénelage le cercle résultant, l'astuce est de produire un plus grand masque puis l'échelle vers le bas à l'aide d'un filtre ANTIALIAS: ici est 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 bien meilleur résultat à mon avis.

+1

Mec, les ANTIALIAS ont fait une énorme différence! Merci! = D – ademarizu

+0

Cela a si bien fonctionné pour moi. Pas besoin de concevoir un masque. –