2009-05-20 12 views

risposta

62

Il modo più semplice per farlo è utilizzare le maschere. Crea una maschera in bianco e nero con qualsiasi forma desideri. E mettere quella forma come strato alfa

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

Ecco la maschera che ho usato

alt text


Se si desidera che la dimensione delle miniature di essere variabile è possibile utilizzare l'ImageDraw e disegnare la maschera.

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 si desidera che l'output in formato GIF, allora è necessario utilizzare la funzione incolla invece di 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) 

Nota che ho fatto le seguenti modifiche:

  • La maschera è ora invertita. Il bianco è stato sostituito con il nero e viceversa.
  • Mi sto convertendo in "P" con una tavolozza "adattiva". In caso contrario, PIL utilizzerà solo colori sicuri per il Web e il risultato sarà pessimo.
  • Sto aggiungendo informazioni trasparenza all'immagine

Prego notare: C'è un grosso problema con questo approccio. Se l'immagine gif contiene parti nere, anche tutte diventeranno trasparenti. Puoi aggirare questo scegliendo un altro colore per la trasparenza. Consiglio vivamente di utilizzare il formato PNG per questo. Ma se non puoi, è il meglio che potresti fare.

+0

Ottimo! E che dire dell'uscita di gif invece di png? Immagino che gif non gestisca alpha, vero? – ohnoes

+0

Gif non supporta la trasparenza del canale alfa. Supporta solo l'impostazione di un colore come trasparente. Tuttavia, ho apportato le modifiche necessarie per produrre il risultato in gif. –

+0

ottima risposta. mentre posso applicare facilmente questa tecnica alle immagini salvate mi sono imbattuto in un problema applicando la maschera all'interno di python. qualsiasi possibilità di dare un'occhiata a questa domanda: http://stackoverflow.com/questions/20150552/modify-the-alpha-channel-of-an-image-as-part-of-an-image-processing-workflow – zach

19

vorrei aggiungere alla risposta già accettato una soluzione antialias il cerchio risultante, il trucco è quello di produrre una maschera più grande e poi scala verso il basso utilizzando un filtro antialias: Ecco il codice

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) 

questo produce un risultato molto migliore a mio parere.

+1

Amico, gli ANTIALIAS hanno fatto un'enorme differenza! Grazie! = D – ademarizu

+0

Questo ha funzionato per me così bene. Non c'è bisogno di progettare una maschera. –