在创建缩略图时,如何让PIL考虑到最短的一面?

时间:2010-12-01 04:48:28

标签: python image math python-imaging-library resize

目前,对于我下面的功能...图像将根据最长边调整大小。

基本上图像的高度较大,高度为200px。宽度只是...无论......

如果图像宽度较大,宽度将为200px,高度将相应调整。

如何翻转它?!我希望这个功能考虑到最短的一面。

我写错了这个函数吗?

def create_thumbnail(f, width=200, height=None, pad = False):
    #resizes the longest side!!! doesn't even care about the shortest side
    #this function maintains aspect ratio.
    if height==None: height=width
    im = Image.open(StringIO(f))
    imagex = int(im.size[0])
    imagey = int(im.size[1])
    if imagex < width or imagey < height:
        pass
        #return None
    if im.mode not in ('L', 'RGB', 'RGBA'):
        im = im.convert('RGB')
    im.thumbnail((width, height), Image.ANTIALIAS)
    thumbnail_file = StringIO()
    im.save(thumbnail_file, 'JPEG')
    thumbnail_file.seek(0)
    return thumbnail_file

2 个答案:

答案 0 :(得分:2)

使用resize代替thumbnail

thumbnail背后的一点是,可以轻松地缩小图像以适应保留纵横比的特定边界框。这意味着如果您的边界框是正方形,则图像的较长边确定使用的比例。

resize为您提供更直接的控制 - 您可以准确指定所需的尺寸。

实际上,既然你想保留方面,你仍然可以使用缩略图,但你需要捏造边界框。在致电thumbnail之前,请尝试执行以下操作:

old_aspect = float(imagex)/float(imagey)
new_aspect = float(width)/float(height)
if old_aspect < new_aspect:
  height = int(width / old_aspect)
else:
  width = int(height * old_aspect)

答案 1 :(得分:0)

我刚才把这个功能放在一起:

def thumbnail(img, size=150):

    from math import floor
    from PIL import Image

    img = img.copy()

    if img.mode not in ('L', 'RGB'):
        img = img.convert('RGB')

    width, height = img.size

    if width == height:
        img.thumbnail((size, size), Image.ANTIALIAS)

    elif height > width:
        ratio = float(width) / float(height)
        newwidth = ratio * size
        img = img.resize((int(floor(newwidth)), size), Image.ANTIALIAS)

    elif width > height:
        ratio = float(height) / float(width)
        newheight = ratio * size
        img = img.resize((size, int(floor(newheight))), Image.ANTIALIAS)

    return img

image = thumbnail(image, size=600)

它将图像的大小调整为最大尺寸,保留纵横比