最简单的方法是什么来调整图像大小到指定限制区域?

3 投票
1 回答
2366 浏览
提问于 2025-04-16 05:05

我想创建一个函数,像这样:

def generateThumbnail(self, width, height):
     """
     Generates thumbnails for an image
     """
     im = Image.open(self._file)
     im.thumbnail((width, height), Image.ANTIALIAS)
     im.save(self._path + str(width) + 'x' + 
             str(height) + '-' + self._filename, "JPEG")

这个函数可以接收一个文件并调整它的大小。

现在的这个函数运行得很好,但在必要的时候它不会裁剪图片。

比如说,如果给定的是一个长方形的图片,而我们需要把它调整成正方形(宽度和高度相等),那么就需要进行一些居中裁剪。

1 个回答

6

在调整图片大小之前,你需要先把图片裁剪好。简单来说,就是要找出源图片中最大的矩形区域,这个区域的宽高比要和缩略图的宽高比一致。然后再把多余的部分裁掉,最后再调整到缩略图的尺寸。下面是一个可以计算裁剪区域大小和位置的函数:

def cropbbox(imagewidth,imageheight, thumbwidth,thumbheight):
    """ cropbbox(imagewidth,imageheight, thumbwidth,thumbheight)

        Compute a centered image crop area for making thumbnail images.
          imagewidth,imageheight are source image dimensions
          thumbwidth,thumbheight are thumbnail image dimensions

        Returns bounding box pixel coordinates of the cropping area
        in this order (left,upper, right,lower).
    """
    # determine scale factor
    fx = float(imagewidth)/thumbwidth
    fy = float(imageheight)/thumbheight
    f = fx if fx < fy else fy

    # calculate size of crop area
    cropheight,cropwidth = int(thumbheight*f),int(thumbwidth*f)

    # for centering use half the size difference of the image and the crop area
    dx = (imagewidth-cropwidth)/2
    dy = (imageheight-cropheight)/2

    # return bounding box of centered crop area on source image
    return dx,dy, cropwidth+dx,cropheight+dy


if __name__=='__main__':

    print("===")
    bbox = cropbbox(1024,768, 128,128)
    print("cropbbox(1024,768, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(768,1024, 128,128)
    print("cropbbox(768,1024, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 96,128)
    print("cropbbox(1024,1024, 96,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 128,96)
    print("cropbbox(1024,1024, 128,96): {}".format(bbox))

确定好裁剪区域后,调用 im.crop(bbox),然后在返回的图片上调用 im.thumbnail(...)

撰写回答