如何让PIL在创建缩略图时考虑最短边?

1 投票
2 回答
2886 浏览
提问于 2025-04-16 07:51

目前,我的这个函数会根据图片的最长边来调整大小。

简单来说,如果图片的高度更大,那么高度会被设置为200像素,宽度就随便了。

如果图片的宽度更大,那么宽度会被设置为200像素,高度会相应调整。

我想把这个逻辑反过来!我希望这个函数能考虑到最短边。

我是不是写错这个函数了??

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 个回答

1

我之前写了一个函数:

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)

这个函数可以把一张图片缩小到最长边不超过指定的大小,同时保持图片的宽高比例。

2

resize代替thumbnail

thumbnail的主要目的是让你可以轻松地把图片缩小到一个特定的框里,同时保持图片的比例。这意味着,如果你的框是一个正方形,图片的长边就会决定缩放的大小。

resize则让你可以更直接地控制——你可以准确地指定你想要的大小。

其实,如果你想保持比例,还是可以使用thumbnail,但你需要调整一下框的大小。在你调用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)

撰写回答