Image. Fromarray Just Produces Black Image

I'm trying to save a numpy matrix as a grayscale image using Image.fromarray. It seems to work on a random matrix, but not on a particular one (where there should appear a circle). Can anyone explain what I'm doing wrong?

from PIL import Image
import numpy as np
radius = 0.5
size = 10
x,y = np.meshgrid(np.linspace(-1,1,size),np.linspace(-1,1,size))
f = np.vectorize(lambda x,y: ( 1.0 if x*x + y*y < radius*radius else 0.0))
z = f(x,y)
print(z)
zz = np.random.random((size,size))
img = Image.fromarray(zz,mode='L') #replace z with zz and it will just produce a black image
img.save('my_pic.png')
4

1 Answer

Image.fromarray is poorly defined with floating-point input; it's not well documented but the function assumes the input is laid-out as unsigned 8-bit integers.

To produce the output you're trying to get, multiply by 255 and convert to uint8:

z = (z * 255).astype(np.uint8)

The reason it seems to work with the random array is that the bytes in this array, when interpreted as unsigned 8-bit integers, also look random. But the output is not the same random array as the input, which you can check by doing the above conversion on the random input:

np.random.seed(0)
zz = np.random.rand(size, size)
Image.fromarray(zz, mode='L').save('pic1.png')
Image.fromarray((zz * 255).astype('uint8'), mode='L').save('pic2.png')

Since the issue doesn't seem to be reported anywhere, I reported it on github:

4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest