How to create circular thumbnails with PIL?

How to create thumbnails of circular images using PIL? The space outside the circle should be transparent.

Fragments will be highly appreciated, thanks in advance.

+38
python thumbnails python-imaging-library circle
May 20 '09 at 20:26
source share
2 answers

The easiest way to do this is to use masks. Create a black and white mask with any shape you want. And use putalpha to put this shape as an alpha layer:

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

Here is the mask I used:

alt text




If you want the thumbnail size to be variable, you can use ImageDraw and draw a mask:

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



If you want output in GIF, you need to use the insert function instead of 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) 

Please note that I made the following changes:

  • The mask is now upside down. White has been replaced by black and vice versa.
  • I convert to "P" with an "adaptive" palette. Otherwise, PIL will only use web-safe colors, and the result will look bad.
  • I am adding transparency information to the image.

Please note : there is a big problem with this approach. If the GIF image contains black parts, all of them will also become transparent. You can get around this by choosing a different color for transparency. I highly recommend you use the PNG format for this. But if you cannot, then this is the best you can do.

+70
May 20 '09 at 20:37
source share

I would like to add to the already accepted answer the solution for the antialiases of the resulting circle, the trick is to create a large mask and then scale it using the ANTIALIAS filter: here is the 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) 

this gives a much better result, in my opinion.

+26
Mar 11 '14 at 20:31
source share



All Articles