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

时间:2015-02-09 10:20:56

标签: python python-imaging-library 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图像,文档不会对此错误说些什么。

2 个答案:

答案 0 :(得分:23)

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

编辑: 我实际上误解了文档,你是对的,它不在那里。但是从我在这里尝试的,似乎没有传递第二个参数,大小必须匹配。如果您想保留第二张图片的大小并将其放在第一张图片的左上角,请执行以下操作:

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

答案 1 :(得分: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),但它适用于小图像。也许有人可以改进代码以提高效率。

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