PIL : How to write array to image ???

Peter Otten __peter__ at web.de
Sat Oct 3 17:56:21 EDT 2009


Martin wrote:

> Dear group
> 
> I'm trying to use PIL to write an array (a NumPy array to be exact) to
> an image.
> Peace of cake, but it comes out looking strange.
> 
> I use the below mini code, that I wrote for the purpose. The print of
> a looks like expected:
> 
> [[ 200.  200.  200. ...,    0.    0.    0.]
>  [ 200.  200.  200. ...,    0.    0.    0.]
>  [ 200.  200.  200. ...,    0.    0.    0.]
>  ...,
>  [   0.    0.    0. ...,  200.  200.  200.]
>  [   0.    0.    0. ...,  200.  200.  200.]
>  [   0.    0.    0. ...,  200.  200.  200.]]
> 
> But the image looks nothing like that.
> 
> Please see the images on:
> http://hvidberg.net/Martin/temp/quat_col.png
> http://hvidberg.net/Martin/temp/quat_bw.png
> 
> or run the code to see them locally.
> 
> Please – what do I do wrong in the PIL part ???
> 
> :-? Martin
> 
> 
> 
> import numpy as np
> from PIL import Image
> from PIL import ImageOps
> 
> maxcol = 100
> maxrow = 100
> 
> a = np.zeros((maxcol,maxrow),float)
> 
> for i in range(maxcol):
>     for j in range(maxrow):
>         if (i<(maxcol/2) and j<(maxrow/2)) or (i>=(maxcol/2) and j>=
> (maxrow/2)):
>             a[i,j] = 200
>         else:
>             a[i,j] = 0
> 
> print a
> 
> pilImage = Image.fromarray(a,'RGB')
> pilImage.save('quat_col.png')
> pilImage = ImageOps.grayscale(pilImage)
> pilImage.save('quat_bw.png')

The PIL seems to copy the array contents directly from memory without any 
conversions or sanity check. In your example The float values determine the 
gray value of 8 consecutive pixels.

If you want a[i,j] to become the color of the pixel (i, j) you have to use 
an array with a memory layout that is compatible to the Image.
Here are a few examples:

>>> import numpy
>>> from PIL import Image

>>> a = numpy.zeros((100, 100), numpy.uint8)
>>> a[:50, :50] = a[50:, 50:] = 255
>>> Image.fromarray(a).save("tmp1.png")

>>> b = numpy.zeros((100, 100, 3), numpy.uint8)
>>> b[:50, :50, :] = b[50:, 50:, :] = [255, 0, 0]
>>> Image.fromarray(b).save("tmp2.png")

>>> c = numpy.zeros((100, 100), numpy.uint32)
>>> c[:50, :50] = c[50:, 50:] = 0xff808000
>>> Image.fromarray(c, "RGBA").save("tmp3.png")

Peter




More information about the Python-list mailing list