Curtis Milligan
Curtis Milligan

Reputation: 1

Creating a grayscale image from an array of values

I am trying to create a grayscale image from an array of values that range from 0 to 1. here is an example of two of the arrays I have.

[[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 ]]

[[0.33333333 0.22222222 0.33333333]
 [0.22222222 0.44444444 0.11111111]
 [0.44444444 0.11111111 0.11111111]]

the shape of the array is always a square and the the amount that the values deviate from 0.5 varies. I more or less want values of 1 to be white and 0 to be black. Is there a relatively simple way to do this using a module such as matplotlib or pillow? (it doesn't have to be one of those two).

I have tried following some tutorials, but they all used hexadecimal value lists or integer values and don't understand the method enough to make them work with floats.

Upvotes: 0

Views: 3248

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207375

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

enter image description here

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308111

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

enter image description here

Upvotes: 1

Related Questions