PIL : How to write array to image ???

Discussion in 'Python' started by Martin, Oct 3, 2009.

  1. Martin

    Martin Guest

    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')
    Martin, Oct 3, 2009
    #1
    1. Advertising

  2. Martin

    Robert Kern Guest

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


    You are telling it the wrong mode information. If you want an RGB image, you
    need to give it a uint8 array with shape (height, width, 3). Exactly what are
    you trying to do? I can't infer that from your code.

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Oct 3, 2009
    #2
    1. Advertising

  3. Martin

    Peter Otten Guest

    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
    Peter Otten, Oct 3, 2009
    #3
  4. Martin

    Martin Guest

    On Oct 3, 11:56 pm, Peter Otten <> wrote:
    > 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


    Thanks All - That helped a lot...

    The working code ended with:


    imga = np.zeros((imgL.shape[1],imgL.shape[0]),np.uint8)
    for ro in range(imgL.shape[1]):
    for co in range(imgL.shape[0]):
    imga[ro,co] = imgL[ro,co]
    Image.fromarray(imga).save('_a'+str(lev)+'.png')
    Martin, Oct 4, 2009
    #4
  5. Martin

    Mart. Guest

    On Oct 4, 9:47 am, Martin <> wrote:
    > On Oct 3, 11:56 pm, Peter Otten <> wrote:
    >
    >
    >
    >
    >
    > > 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

    >
    > Thanks All - That helped a lot...
    >
    > The working code ended with:
    >
    >         imga = np.zeros((imgL.shape[1],imgL.shape[0]),np.uint8)
    >         for ro in range(imgL.shape[1]):
    >             for co in range(imgL.shape[0]):
    >                 imga[ro,co] = imgL[ro,co]
    >         Image.fromarray(imga).save('_a'+str(lev)+'.png')


    Without knowing how big your image is (can't remember if you said!).
    Perhaps rather than looping in the way you might in C for example, the
    numpy where might be quicker if you have a big image. Just a
    thought...
    Mart., Oct 4, 2009
    #5
  6. Martin

    Martin Guest

    On Oct 4, 10:16 pm, "Mart." <> wrote:
    > On Oct 4, 9:47 am, Martin <> wrote:
    >
    >
    >
    > > On Oct 3, 11:56 pm, Peter Otten <> wrote:

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

    >
    > > Thanks All - That helped a lot...

    >
    > > The working code ended with:

    >
    > >         imga = np.zeros((imgL.shape[1],imgL.shape[0]),np.uint8)
    > >         for ro in range(imgL.shape[1]):
    > >             for co in range(imgL.shape[0]):
    > >                 imga[ro,co] = imgL[ro,co]
    > >         Image.fromarray(imga).save('_a'+str(lev)+'.png')

    >
    > Without knowing how big your image is (can't remember if you said!).
    > Perhaps rather than looping in the way you might in C for example, the
    > numpy where might be quicker if you have a big image. Just a
    > thought...


    And a good thought too... I use to teach ansi C at Univ. many ears
    ago, and it's still one of my favorits. But I prefere Python for this
    type of work. Python have a much faster develop time, is much easier
    to write (fewer linees, simpler syntax) and is much more 'hot' in
    these days. Finally my favorit GIS and RS applications support Python
    out-of-the-box.

    :) Martin
    Martin, Oct 5, 2009
    #6
  7. Martin

    Mart. Guest

    On Oct 5, 5:14 pm, Martin <> wrote:
    > On Oct 4, 10:16 pm, "Mart." <> wrote:
    >
    >
    >
    >
    >
    > > On Oct 4, 9:47 am, Martin <> wrote:

    >
    > > > On Oct 3, 11:56 pm, Peter Otten <> wrote:

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

    >
    > > > Thanks All - That helped a lot...

    >
    > > > The working code ended with:

    >
    > > >         imga = np.zeros((imgL.shape[1],imgL.shape[0]),np.uint8)
    > > >         for ro in range(imgL.shape[1]):
    > > >             for co in range(imgL.shape[0]):
    > > >                 imga[ro,co] = imgL[ro,co]
    > > >         Image.fromarray(imga).save('_a'+str(lev)+'.png')

    >
    > > Without knowing how big your image is (can't remember if you said!).
    > > Perhaps rather than looping in the way you might in C for example, the
    > > numpy where might be quicker if you have a big image. Just a
    > > thought...

    >
    > And a good thought too... I use to teach ansi C at Univ. many ears
    > ago, and it's still one of my favorits. But I prefere Python for this
    > type of work. Python have a much faster develop time, is much easier
    > to write (fewer linees, simpler syntax) and is much more 'hot' in
    > these days. Finally my favorit GIS and RS applications support Python
    > out-of-the-box.
    >
    > :) Martin


    I wasn't advocating doing it in c just that you could speed up your
    program considerably by not looping and using some of the numpy array
    options.
    Mart., Oct 5, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paradox

    Python Image Conversion with PIL

    Paradox, Jul 14, 2003, in forum: Python
    Replies:
    0
    Views:
    358
    Paradox
    Jul 14, 2003
  2. Daniel Mark
    Replies:
    1
    Views:
    702
    Fredrik Lundh
    Sep 25, 2006
  3. Andrew
    Replies:
    0
    Views:
    531
    Andrew
    Apr 5, 2007
  4. Sverre
    Replies:
    2
    Views:
    3,525
    Sverre
    Dec 17, 2009
  5. Dave Griffith

    Image::Magick->Write() doesn't want to write

    Dave Griffith, Nov 16, 2009, in forum: Perl Misc
    Replies:
    2
    Views:
    221
    Dave Griffith
    Nov 16, 2009
Loading...

Share This Page