Reputation: 45
I am trying to save a 2D list as an image in python (greyscale image) so 0 values in the array would be black and 255 would be white. For example:
255 255 255
255 0 255
255 0 255
255 0 255
255 255 255
Would save an l like shape. I have tried the following code utilising the PIL library as suggested by other questions on stack overflow:
WIDTH, HEIGHT = img.size
imgData = list(img.getdata())
imgData = [imgData[offset:offset + WIDTH] for offset in range(0, WIDTH * HEIGHT, WIDTH)]
#to print the image
for row in data:
print(' '.join('{:3}'.format(value) for value in row))
imgData = np.array(imgData)
**IMG VALUES AUGMENTED HERE**
newimg = Image.new('L', (WIDTH, HEIGHT), 'white')
newimg.putdata(imgData)
newimg.save('C:/File/Name.png')
However the image this creates does not reflect the list at all. If I was to have the 0s and 255s in different positions the same image is created. Anyone know a solution?
Upvotes: 0
Views: 1213
Reputation: 207465
As your example is lacking any input data, I have just typed it in as you describe, made the image and then enlarged it. I also artificially added a red border so you can see the extent of it on StackOverflow's white background:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
pixels = [[255,255,255],
[255,0,255],
[255,0,255],
[255,0,255],
[255,255,255]]
# Make list of pixels into Image
im = Image.fromarray(np.array(pixels,dtype=np.uint8))
im.save('result.png')
Upvotes: 1
Reputation: 5660
Instead of:
newimg.putdata(imgData)
you need the line:
newimg.putdata([j[0] for i in imgData for j in i])
The grayscale data is specified in a 1d list, not a 2d list.
This creates the list:
>>> [j[0] for i in imgData for j in i]
[255, 255, 255, 255, 0, 255, 255, 0, 255, 255, 0, 255, 255, 255, 255]
Which is:
[255, 255, 255,
255, 0 , 255,
255, 0 , 255,
255, 0 , 255,
255, 255, 255]
EDIT
The above solution works if you edit imgData
with imgData[0][0] = [0, 0, 0, 255]
. If you're editing imgData
with imgData[0][0] = 0
, then you'll need the line to be:
[j[0] if hasattr(j, '__iter__') else j for i in imgData for j in i]
or, you can make it nicer with:
imgData = np.array([[j[0] for j in i] for i in imgData])
imgData[0][0] = 0
newimg.putdata(imgData.flatten())
Upvotes: 0