I think the answer is wrong. The Image.fromarray( ____ , 'L') function seems to only work properly with an array of integers between 0 and 255. I use the np.uint8 function for this.
You can see this demonstrated if you try to make a gradient.
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray(np.uint8(mat * 255) , 'L')
img.show()
Makes a clean gradient
vs
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray( mat , 'L')
img.show()
Has the same kind of artifacting.
Answer from Nathan on Stack OverflowI think the answer is wrong. The Image.fromarray( ____ , 'L') function seems to only work properly with an array of integers between 0 and 255. I use the np.uint8 function for this.
You can see this demonstrated if you try to make a gradient.
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray(np.uint8(mat * 255) , 'L')
img.show()
Makes a clean gradient
vs
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray( mat , 'L')
img.show()
Has the same kind of artifacting.
If I understood you question, you want to get a grayscale image using PIL.
If this is the case, you do not need to multiply each pixels by 255.
The following worked for me
import numpy as np
from PIL import Image
# Creates a random image 100*100 pixels
mat = np.random.random((100,100))
# Creates PIL image
img = Image.fromarray(mat, 'L')
img.show()
This is easily done with PIL/Pillow. Create a new grayscale image of the proper size, and convert each array value to the range 0-255 and copy it in. I added a resize at the end to make the pixels easier to see.
from PIL import Image
array1 = [[0.48, 0.4, 0.56, 0.32, 0.52],
[0.36, 0.56, 0.56, 0.68, 0.56],
[0.32, 0.72, 0.88, 0.44, 0.56],
[0.56, 0.64, 0.76, 0.52, 0.48],
[0.32, 0.88, 0.56, 0.52, 0.4 ]]
width1 = 5
height1 = 5
im = Image.new('L', (width1, height1))
pix = im.load()
for y in range(height1):
for x in range(width1):
pix[x, y] = int(array1[y][x] * 255.9999)
im = im.resize((width1 * 10, height1 * 10), resample=Image.NEAREST)
im.save(r'c:\temp\temp.png')

PIL can create a PIL Image directly from an array:
from PIL import Image
import numpy as np
# Make our randomness repeatable, and generate a 5x4 array of pixels
np.random.seed(42)
px = np.random.random((4,5))
That looks like this:
array([[0.37454012, 0.95071431, 0.73199394, 0.59865848, 0.15601864],
[0.15599452, 0.05808361, 0.86617615, 0.60111501, 0.70807258],
[0.02058449, 0.96990985, 0.83244264, 0.21233911, 0.18182497],
[0.18340451, 0.30424224, 0.52475643, 0.43194502, 0.29122914]])
Now multiply up by 255, convert to np.uint8 and make into PIL Image
p = Image.fromarray((px*255.9999).astype(np.uint8))
# We are finished, but enlarge for illustrative purposes
p = p.resize((50, 40), resample=Image.Resampling.NEAREST)
p.save('result.png')

Pillow cannot read from array gray image?
python - Turning a Large Matrix into a Grayscale Image - Stack Overflow
python - How to change an image to grayscale represented as a NumPy array - Stack Overflow
How do I convert from grayscale to black and white?
Your array of "binary values" is an array of bytes?
If so, you can do (using Pillow) after resizing it:
from PIL import Image
im = Image.fromarray(arr)
And then im.show() to see it.
If your array has only 0's and 1's (1-bit depth or b/w) you may have to multiply it to 255
im = Image.fromarray(arr * 255)
Here an example:
>>> arr = numpy.random.randint(0,256, 100*100) #example of a 1-D array
>>> arr.resize((100,100))
>>> im = Image.fromarray(arr)
>>> im.show()

Edit (2018):
This question was written in 2011 and Pillow changed ever since requiring to use the mode='L' parameter when loading with fromarray.
Also on comments below it was said arr.astype(np.uint8) was needed as well, but I have not tested it
Using PIL is not really needed, you can plot the array directly with pyplot (see below). To save to a file, you could use plt.imsave('fname.png', im).

Code below.
import numpy as np
import matplotlib.pyplot as plt
x = (np.random.rand(1754**2) < 0.5).astype(int)
im = x.reshape(1754, 1754)
plt.gray()
plt.imshow(im)
You can also use plt.show(im) to display image in new window.
Two issues. Firstly, you are not converting to greyscale. Secondly, the whole point of numpy is to vectorise and avoid for loops because they are slow.
So starting with this image:

You want something like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Load coins and convert to greyscale
grey = np.array(Image.open('coins.png').convert('L'))
# Threshold at 128
thresholded=((grey>128)*255).astype(np.uint8)
# Save
Image.fromarray(thresholded).save('result.png')

Sruthi V is right. enumerate() returns a tuple.
So instead of
if item < 128
it should be
if item[1] < 128
Or you could just remove enumerate() entirely if you aren't using it. It seems it will work fine without it.
Consider the following image:
Image
If you zoom in, you will observe that the picture contains pixels of the form (0,0,0,x) in RGBA format (I have used pillow to verify this btw). What I want to do is if the pixel's alpha is less than equal to 200, then write (0,0,0,0) at the pixel's place, and if it is greater than 200 then write (0,0,0,255) at the pixel's place.
Here's my code rn:
from PIL import Image
import numpy as np
def inp_gen(img_path):
im = Image.open(img_path, 'r')
pix_vals = list(im.getdata())
layer = [x[3] for x in pix_vals]
for j in layer:
if j <= 200:
layer[layer.index(j)] = 0
if j > 200:
layer[layer.index(j)] = 1
return layer
def render_img(img_data):
image_data = [(0,0,0,255*x) for x in img_data]
data = np.array(image_data, dtype=np.uint8).T
image = Image.fromarray(data)
image.show()
render_img(img_gen("Path to image in drive link on my PC"))Sadly, this does not give me the output I want:
Output
So what should I do now?