finefoot
finefoot

Reputation: 11224

TypeError: Cannot handle this data type - Wrong mode for `PIL.Image.fromarray`?

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:

figure

Upvotes: 1

Views: 1049

Answers (2)

finefoot
finefoot

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

figure

Upvotes: 0

Sheldore
Sheldore

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

enter image description here

Upvotes: 1

Related Questions