如何使用PIL生成圆形缩略图?

时间:2009-05-20 20:26:28

标签: python thumbnails python-imaging-library geometry

如何使用PIL生成圆形图像缩略图? 圆圈外的空间应该是透明的。

小组报非常感谢,提前谢谢。

4 个答案:

答案 0 :(得分:71)

最简单的方法是使用面具。使用您想要的任何形状创建黑白面具。并使用putalpha将该形状作为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')

这是我使用的面具:

alt text


如果您希望缩略图大小可变,可以使用ImageDraw并绘制掩码:

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

如果您想要GIF中的输出,那么您需要使用粘贴功能而不是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)

请注意,我做了以下更改:

  • 现在倒置了面具。白色 被黑色取代,反之亦然。
  • 我正在使用'自适应'调色板转换为'P'。否则,PIL将仅使用Web安全颜色,结果看起来很糟糕。
  • 我正在为图片添加透明度信息。

请注意:这种方法存在很大问题。如果GIF图像包含黑色部分,则所有这些部分也将变为透明。您可以通过为透明度选择另一种颜色来解决此问题。 我强烈建议你使用PNG格式。但如果你不能那么那就是你能做的最好的事情。

答案 1 :(得分:27)

我想在已经接受的答案中添加一个解决方案来解决生成的圆圈,诀窍是生成一个更大的掩码,然后使用ANTIALIAS过滤器将其缩小: 这是代码

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)

这在我看来产生了更好的结果。

答案 2 :(得分:1)

对@DRC解决方案进行了轻微修改,以也支持已经具有透明度的图像。他将Alpha通道设置为圆圈外的0(不可见),内部为255(不透明),因此我使用darker,它占用了面具的 min 和原始的Alpha通道(可以在0-255之间的任何位置):-)

from PIL import Image, ImageChops, ImageDraw

def crop_to_circle(im):
    bigsize = (im.size[0] * 3, im.size[1] * 3)
    mask = Image.new('L', bigsize, 0)
    ImageDraw.Draw(mask).ellipse((0, 0) + bigsize, fill=255)
    mask = mask.resize(im.size, Image.ANTIALIAS)
    mask = ImageChops.darker(mask, im.split()[-1])
    im.putalpha(mask)

im = Image.open('0.png').convert('RGBA')
crop_to_circle(im)
im.save('cropped.png')

答案 3 :(得分:0)

非常感谢。我找了几个小时,你的主意就解决了。

与此其他脚本一起。 PIL round edges and add border 对我来说很合适。

from PIL import Image
from PIL import ImageDraw, ImageChops

def add_corners( im, rad=100):
    circle = Image.new('L', (rad * 2, rad * 2), 0)
    draw = ImageDraw.Draw(circle)
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)
    alpha = Image.new('L', im.size, "white")
    w, h = im.size
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))

    alpha = ImageChops.darker(alpha, im.split()[-1])

    im.putalpha(alpha)
    return im

im = Image.open ('AceOfSpades.png').convert('RGBA')

im = add_corners (im, 24)

im.show()
im.save("perfect.png")

Name this image AceOfSpades.png for testing