Jack Timber
Jack Timber

Reputation: 45

Saving list as an image in python

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

Answers (2)

Mark Setchell
Mark Setchell

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

enter image description here

Upvotes: 1

rassar
rassar

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

Related Questions