Reputation: 11224
I'm trying to use PIL.Image.fromarray
:
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
a = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]]])
im = Image.fromarray(a, mode="RGB")
im.save("test.png")
plt.imshow(im)
plt.show()
I expected to see 3 pixels red, green and blue.
However, if I omit mode
keyword parameter as shown in the docs example, I get:
TypeError: Cannot handle this data type
And if I set mode="RGB"
, the saved image file test.png
and the matplotlib
window both look like this:
Upvotes: 1
Views: 1049
Reputation: 11224
According to https://pillow.readthedocs.io/en/latest/handbook/concepts.html#concept-modes mode RGB
should be 3x8-bit pixels. However, numpy.ndarray
has type int64
by default:
>>> a = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]]])
>>> a.dtype
dtype('int64')
That's where
TypeError: Cannot handle this data type
came from. If I set the correct 8-bit dtype
keyword for the array, everything works fine, even without specifying the mode
keyword:
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
a = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]]])
im = Image.fromarray(a, mode="RGB")
im.save("test.png")
plt.imshow(im)
plt.show()
Upvotes: 0
Reputation: 39042
Stack your three arrays and convert them to uint8
type based on this and this answer.
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
a = (np.dstack(([255, 0, 0],[0, 255, 0],[0, 0, 255]))).astype(np.uint8)
im = Image.fromarray(a, mode="RGB")
im.save("test.png")
plt.imshow(im)
plt.show()
Alternate option is to add extra dimension to your input array making it of shape (1, 3, 3)
a = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]]], dtype=np.uint8)
im = Image.fromarray(a, mode="RGB")
Upvotes: 1