pythonthumbnailspython-imaging-librarygeometry

How do I generate circular thumbnails with PIL?


How do I generate circular image thumbnails using PIL? The space outside the circle should be transparent.

Snippets would be highly appreciated, thank you in advance.


Solution

  • The easiest way to do it is by using masks. Create a black and white mask with any shape you want. And use putalpha to put that 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 the 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 the output in GIF then you need to use the paste 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)
    

    Note that I did the following changes:

    Please note: There is a big issue with this approach. If the GIF image contained black parts, all of them will become transparent as well. You can work around this by choosing another color for the transparency. I would strongly advise you to use PNG format for this. But if you can't then that is the best you could do.