2009-05-20 10 views

Odpowiedz

62

Najprostszym sposobem na to jest użycie masek. Utwórz czarno-białą maskę o dowolnym kształcie. I umieścić ten kształt jako warstwa 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') 

Oto maska ​​użyłem

alt text


Jeśli chcesz rozmiar miniatur być zmienna można użyć ImageDraw i narysować maska.

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

Jeśli chcesz wyjście w formacie GIF następnie trzeba użyć funkcji wklejania zamiast 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) 

Należy zauważyć, że robiłam następujące zmiany:

  • Maska jest teraz odwrócona. Biały został zamieniony na czarny i odwrotnie.
  • Konwertuję na "P" z paletą "adaptacyjną". W przeciwnym razie PIL użyje tylko kolorów bezpiecznych dla strony internetowej, a wynik będzie wyglądał źle.
  • Dodaję informacji o przezroczystości do obrazu

Uwaga: Istnieje duży problem z tym podejściem. Jeśli obraz gif zawierał czarne części, wszystkie z nich również staną się przezroczyste. Możesz obejść to, wybierając inny kolor dla przezroczystości. Zdecydowanie radzę użyć formatu PNG do tego. Ale jeśli nie możesz, to jest to najlepsze, co możesz zrobić.

+0

Świetnie! A co z wyprowadzaniem gif zamiast png? Przypuszczam, że gif nie obsługuje alfy, prawda? – ohnoes

+0

Gif nie obsługuje przezroczystości kanału alfa. Obsługuje tylko ustawienie jednego koloru jako przezroczystego. Jednak wprowadziłem niezbędne dostosowanie, aby wyprowadzić wynik w gif. –

+0

świetna odpowiedź. podczas gdy mogę łatwo zastosować tę technikę do zapisanych obrazów, natknąłem się na problem nakładający maskę w pythonie. możesz rzucić okiem na to pytanie: http://stackoverflow.com/questions/20150552/modify-the-alpha-channel-of-an-image-as-part-of-an-image-processing-workflow – zach

19

Chciałbym dodać do już przyjętego odpowiedź rozwiązanie Wygładzanie powstałego okręgu, sztuką jest wyprodukować większą maskę a następnie skalować go w dół za pomocą filtra Wygładzanie: Oto kod

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) 

daje to o wiele lepszy wynik w mojej opinii.

+1

Dude, ANTIALIAS zrobiły ogromną różnicę! Dzięki! = D – ademarizu

+0

To zadziałało dla mnie tak dobrze. Nie ma potrzeby projektowania maski. –