枕头通过裁剪而不是保留纵横比来创建缩略图

时间:2017-05-02 09:14:39

标签: python-3.x thumbnails pillow

默认情况下,thumbnail方法会保留纵横比,这可能会导致缩略图尺寸不一致。

  

Image.thumbnail(size,resample = 3)   将此图像转换为缩略图。此方法修改图像以包含其自身的缩略图版本,不大于给定大小。 此方法计算适当的缩略图大小以保留图像的方面,调用draft()方法配置文件阅读器(如果适用),最后调整图像大小。

我希望它裁剪图像,以便缩略图填充所提供的整个画布,这样图像就不会变形。例如,图像上的Image.thumbnail((200, 200), Image.ANTIALIAS) 640×480将通过480裁剪到中心480,然后缩小到200乘200(不是199或201)。怎么办呢?

1 个答案:

答案 0 :(得分:4)

这最容易分两个阶段进行:首先裁剪,然后生成缩略图。裁剪到给定的宽高比是很常见的,在PILLOW中确实应该有它的功能,但据我所知,没有。这是一个简单的实现,猴子修补到Image类:

from PIL import Image

class _Image(Image.Image):

    def crop_to_aspect(self, aspect, divisor=1, alignx=0.5, aligny=0.5):
        """Crops an image to a given aspect ratio.
        Args:
            aspect (float): The desired aspect ratio.
            divisor (float): Optional divisor. Allows passing in (w, h) pair as the first two arguments.
            alignx (float): Horizontal crop alignment from 0 (left) to 1 (right)
            aligny (float): Vertical crop alignment from 0 (left) to 1 (right)
        Returns:
            Image: The cropped Image object.
        """
        if self.width / self.height > aspect / divisor:
            newwidth = int(self.height * (aspect / divisor))
            newheight = self.height
        else:
            newwidth = self.width
            newheight = int(self.width / (aspect / divisor))
        img = self.crop((alignx * (self.width - newwidth),
                         aligny * (self.height - newheight),
                         alignx * (self.width - newwidth) + newwidth,
                         aligny * (self.height - newheight) + newheight))
        return img

Image.Image.crop_to_aspect = _Image.crop_to_aspect

鉴于此,你可以写

cropped = img.crop_to_aspect(200,200)
cropped.thumbnail((200, 200), Image.ANTIALIAS)