如何使用 Pillow 将图像粘贴到更大的图像上?

How to paste an image onto a larger image using Pillow?

我有一个相当简单的代码文件:

from PIL import Image
til = Image.new("RGB",(50,50))
im = Image.open("tile.png") #25x25
til.paste(im)
til.paste(im,(23,0))
til.paste(im,(0,23))
til.paste(im,(23,23))
til.save("testtiles.png")

但是,当我尝试 运行 它时,出现以下错误:

Traceback (most recent call last):
    til.paste(im)
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 1340, in paste
    self.im.paste(im, box)
ValueError: images do not match

导致此错误的原因是什么?它们都是 RGB 图像,文档没有说明这个错误。

问题出在第一次粘贴中 - 根据 PIL 文档 (http://effbot.org/imagingbook/image.htm),如果未传递 "box" 参数,图像的大小必须匹配。

编辑: 我实际上误解了文档,你是对的,它不在那里。但从我在这里的尝试来看,似乎没有传递第二个参数,尺寸必须匹配。如果你想保持第二张图片的大小并将它放在第一张图片的左上角,只需这样做:

...
til.paste(im,(0,0))
...

所以我可能会迟到一点,但也许它可以帮助晚一点的人:

当我遇到同样的问题时,我找不到太多相关信息。 所以我写了一个片段,将一张图片粘贴到另一张图片中。

def PasteImage(source, target, pos):

    # Usage:
    # tgtimg = PIL.Image.open('my_target_image.png')
    # srcimg = PIL.Image.open('my_source_image.jpg')
    # newimg = PasteImage(srcimg, tgtimg, (5, 5))
    # newimg.save('some_new_image.png')
    #

    smap = source.load()
    tmap = target.load()
    for i in range(pos[0], pos[0] + source.size[0]): # Width
        for j in range(pos[1], pos[1] + source.size[1]): # Height
            # For the paste position in the image the position from the top-left
            # corner is being used. Therefore 
            # range(pos[x] - pos[x], pos[x] + source.size[x] - pos[x])
            # = range(0, source.size[x]) can be used for navigating the source image.

            sx = i - pos[0]
            sy = j - pos[1]

            # Change color of the pixels
            tmap[i, j] = smap[sx, sy]

    return target

不一定是最好的方法,因为它大约需要 O(N^2),但它适用于小图像。也许有人可以改进代码以提高效率。

我做的很匆忙,所以它也没有输入验证。 只知道源图像的宽度和高度必须小于或等于目标图像的宽度和高度,否则它会崩溃。 您也可以只粘贴整个图像,而不是部分或 non-rectangular 个图像。