web-dev-qa-db-fra.com

Comment coller une image sur une image plus grande à l'aide de Pillow?

J'ai un fichier de code assez simple:

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")

Cependant, lorsque je tente de l'exécuter, j'obtiens le message d'erreur suivant:

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

Qu'est ce qui cause cette erreur? Ce sont deux images RVB, les documents ne disent rien à propos de cette erreur.

11
user1796160

Le problème est dans le premier collage - selon la documentation de PIL ( http://effbot.org/imagingbook/image.htm ), si aucun argument "box" n'est transmis, les tailles des images doivent correspondre.

EDIT: En fait, j’ai mal compris la documentation, vous avez raison, elle n’est pas là. Mais d'après ce que j'ai essayé ici, il ne semble pas y avoir de deuxième argument, les tailles doivent correspondre. Si vous souhaitez conserver la taille de la seconde image et la placer dans le coin supérieur gauche de la première image, procédez comme suit:

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

Donc, je suis peut-être un peu en retard, mais peut-être que cela aidera les personnes qui viendront après un peu:

Quand j'ai eu le même problème, je n'ai pas trouvé grand chose à ce sujet… .. J'ai donc écrit un extrait de code qui colle une image dans une autre.

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

Ce n’est pas forcément la meilleure approche, car cela prend approximativement O (N ^ 2), mais cela fonctionne pour de petites images. Peut-être que quelqu'un peut améliorer le code pour être plus efficace.

Je l'ai fait rapidement, de sorte qu'il ne dispose pas non plus de validation d'entrée . Sachez simplement que la largeur et la hauteur de l'image source DOIVENT être plus petites ou égales à la largeur et la hauteur de l'image cible, sinon cela planterait ..__ Vous pouvez également ne coller que l’ensemble de l’image, et non des sections ou des images non rectangulaires.

0
JH_WK