在Python中,如何在不调整大小的情况下扩展Python图像库1.1.6的画布?

29 投票
4 回答
16508 浏览
提问于 2025-04-15 15:05

我可能在手册里找错了东西,但我想要做的是把一个图片对象扩展,而不是改变原始图片的大小(拉伸或压缩)。

举个简单的例子:想象一个蓝色的矩形,大小是200 x 100,然后我进行一些操作,得到一个新的图片对象,大小是400 x 300,这个新图片有一个白色的背景,上面放着一个200 x 100的蓝色矩形。如果我能控制扩展的方向,或者新背景的颜色,那就更好了。

基本上,我有一张图片,我会逐步添加内容,但我一开始不知道它会变成多大。

我想我可以先拿到原始对象,做一个稍微大一点的新对象,把原始图片粘贴上去,再画一点东西,然后重复这个过程。这样做可能会消耗很多计算资源。不过,我以为应该有一个函数可以直接实现这个,因为我觉得这是个常见的操作。也许我想错了。

4 个回答

6

你可以考虑用一种完全不同的方法来处理你的图像……把它分成固定大小的小块。这样,当你需要扩展时,只需添加新的图像小块就可以了。当你完成所有计算后,可以确定图像的最终大小,然后创建一个空白的图像,按照需要的大小把小块粘贴进去。这样可以减少你在完成任务时需要复制的内容。

当然,你可能还想把这种分块的图像封装成一个对象,这样其他代码层就看不到这些分块的细节了。

18

根据interjays的回答:

#!/usr/bin/env python

from PIL import Image
import math


def resize_canvas(old_image_path="314.jpg", new_image_path="save.jpg",
                  canvas_width=500, canvas_height=500):
    """
    Resize the canvas of old_image_path.

    Store the new image in new_image_path. Center the image on the new canvas.

    Parameters
    ----------
    old_image_path : str
    new_image_path : str
    canvas_width : int
    canvas_height : int
    """
    im = Image.open(old_image_path)
    old_width, old_height = im.size

    # Center the image
    x1 = int(math.floor((canvas_width - old_width) / 2))
    y1 = int(math.floor((canvas_height - old_height) / 2))

    mode = im.mode
    if len(mode) == 1:  # L, 1
        new_background = (255)
    if len(mode) == 3:  # RGB
        new_background = (255, 255, 255)
    if len(mode) == 4:  # RGBA, CMYK
        new_background = (255, 255, 255, 255)

    newImage = Image.new(mode, (canvas_width, canvas_height), new_background)
    newImage.paste(im, (x1, y1, x1 + old_width, y1 + old_height))
    newImage.save(new_image_path)

resize_canvas()
35

ImageOps.expand这个函数会把图片扩展,但它会在每个方向上添加相同数量的像素。

最简单的方法就是新建一张图片,然后把原来的图片粘贴上去:

newImage = Image.new(mode, (newWidth,newHeight))
newImage.paste(srcImage, (x1,y1,x1+oldWidth,y1+oldHeight))

如果你担心性能问题,可以先把原始图片做得比需要的大,然后在绘制完成后再裁剪。

撰写回答