Home > Blockchain >  PIL Image.paste not pasting small images over a big image
PIL Image.paste not pasting small images over a big image

Time:10-08

I am trying to create a full image and wish to paste smaller images onto it. This is an example of my code.

from PIL import Image
imageWidth=5760
imageHeight=2880
image_sheet = Image.new("RGB", (imageWidth, imageHeight), (255, 255, 255))

This creates an image object having the specifications as mentioned in the arguments. Now I wish to paste an image of size 512*512 on this image.For example,

image=np.zeros((512,512))
image_sheet.paste(image,box=(0,0))    # I am trying to paste image of size 512*512 at upper left location of (0,0) as per the documentation

I get this error :

File "C:\Users\SSHUB\Anaconda3\envs\dl_torch\lib\site-packages\PIL\Image.py", line 1537, in paste
raise ValueError("cannot determine region size; use 4-item box")
ValueError: cannot determine region size; use 4-item box

If I use a 4 item box like this image_sheet.paste(image,box=(0,0,512,512)) , I get the following error :

File "C:\Users\SSHUB\Anaconda3\envs\dl_torch\lib\site-packages\PIL\Image.py", line 1559, in paste
self.im.paste(im, box)
TypeError: color must be int or tuple

I am using pillow 9.0.1. Please guide as to how to fix this issue.

CodePudding user response:

You can't paste a Numpy array into a PIL Image. You need to make the Numpy array into a PIL Image first:

from PIL import Image
import numpy as np

imageWidth=5760
imageHeight=2880
image_sheet = Image.new("RGB", (imageWidth, imageHeight), (255, 255, 255))

# Make little image to paste
image=np.zeros((512,512), dtype=np.uint8)
image_sheet.paste(Image.fromarray(image), ...)

Also, watch out for the dtype !!! Example:

image=np.zeros((512,512))
print(image.dtype)

'float64' !!!! which is UNACCEPTABLE to PIL

Alternatively, you could make the little image directly in PIL:

image_sheet.paste(Image.new("RGB", (512,512), 'red'), ...)

CodePudding user response:

Image.paste() only accepts another Image instance, or a pixel colour (which can be a string, an integer or a tuple, depending on the mode of the image).

You passed in a numpy array, and that's not an image, nor is it a valid pixel colour. Make it an image first, e.g. by using Image.fromarray():

image_sheet.paste(Image.fromarray(image))

perhaps passing in image_sheet.mode as the second argument to Image.fromarray(). I left off the box argument for Image.paste(), because the default is (0, 0).

The way the Image.paste() method is implemented, if you don't pass in an image, it assumes you passed in a pixel colour instead, and in that case you have to specify a 4-value box, hence the first error message. When you do give it a 4-value box, only then can it tell you that what you passed in is not a pixel colour!

  • Related