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!