#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    12
    Rep Power
    0

    Reading binary data into 2-D array


    I have no problem reading a binary image file into a one dimensional array (here with the number of elements equalling in_pixels).

    file = open(in_file, 'rb')
    data = array.array(in_imgtype)
    data.fromfile(file,in_pixels)

    BUT how do I read the same data into a 2-D array (eg in_pixels is arranged in the image as in_rows by in_cols)?

    Thanks.
  2. #2
  3. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    If the number of elements == the number of pixels why worry about using a 2D array? If you know the pixel order (stored in rows or columns) then you can map 2D co-ordinates to a 1D array.

    e.g. stored in rows and assume first pixel in at 0,0
    say width = 100
    say pixel co-orodinate = (x,y) = (10,12)

    pixel = array1D[x*width+y] = array1D[1012]


    Grim
    Last edited by Grim Archon; April 30th, 2004 at 12:42 PM. Reason: removed 2D code
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    12
    Rep Power
    0
    Originally Posted by Grim Archon
    If the number of elements == the number of pixels why worry about using a 2D array? If you know the pixel order (stored in rows or columns) then you can map 2D co-ordinates to a 1D array.

    e.g. stored in rows and assume first pixel in at 0,0
    say width = 100
    say pixel co-orodinate = (x,y) = (10,12)

    pixel = array1D[x*width+y] = array1D[1012]

    Grim
    I suppose I could.... but this becomes more tricky when you want to calculate spatial relationships between elements (e.g. if it is a satellite image and you want to know which element is immediately NW of the element in question...
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2001
    Location
    Houston, TX
    Posts
    383
    Rep Power
    14
    Code:
    f = file('foo', 'rb')
    pixels = []
    row = 0
    col = 0
    for byte in file.read():
        if byte == '\n':
            row += 1
            col = 0
        else:
            pixels[row][col] = byte
            col += 1
    Debian - because life's too short for worrying.
    Best. (Python.) IRC bot. ever.
  8. #5
  9. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    Strike I'm guessing here but I don't think image files have a convenient eol.

    The image file usually has a header which amongst other things will have the dimensions of the image. A bmp for example will have this and the palette used.
    How about this:

    Code:
    def getpixel(x,y):
          return array1D[x*width+y]
    or

    Code:
    array2D = []
    for n in range(0,len(array1D),width):
        array2D.append(array1D[n:n+width])
    
    pixel = array2D[x][y]
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    What do you want to do with the data once you have read it in? What is the purpose behind your question? There are a number of alternatives available to you, and the best one will depend on what you want it for.

    Here are some alternatives off the top of my head:

    1) you cannot create 2D arrays with the array module, but you could create a list of array objects by having a loop that reads in_rows bytes from the file, converts it to an array, and appends it to the list. This is probably closest to the answer that you were seeking.

    2) Use the numpy or numarray extensions to create true 2D arrays. See http://www.pfdubois.com/numpy/ and http://www.stsci.edu/resources/softw...dware/numarray respectively.

    3) use PIL (http://www.pythonware.com/products/pil/) to read the file. This will give you the facility to treat it as an image, rather than a collection of bytes.

    4) read it into a list of lists using the struct module. This is the slowest option, and I would not recommend it.

    Dave - The Developers' Coach
    Last edited by DevCoach; May 1st, 2004 at 06:49 AM.
  12. #7
  13. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    I don't really know enough about the internal structure of an image to comment much here but heres attempt - assuming that a line in the image ends with a '\n' char so can be looped over easily line by line.

    Code:
    #!/usr/bin/env python
    
    array = []
    
    for line in file('image', 'rb'):
        array.append(list(line))
    Note: Yet again these are untested . If anyone tries this and it doesnt work let me know what's wrong since it came straight from my head and might not actually work. At the very least they should give some idea's.

    Anyway I'd probably go with the PIL aproch on this one (depending on what it is you want to do with the data) but then i'm a big fan of PIL so

    Mark.
    Last edited by netytan; May 1st, 2004 at 11:12 AM. Reason: Typos
    programming language development: www.netytan.com Hula

  14. #8
  15. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    I was not guessing really

    Image files are not organised like text files - they are usually binary data with no EOL.

    In general the file formats do not have a one to one relationship between bytes/char and pixels at all as either the pixel information is bigger than a basic data unit and/or the format uses compression. Consider jpegs, png and GIF files.

    So, unless you convert the file from its own structure to something 'flat' and useful using things lke PIL you won't be able to manipulate them by pixel anyway.

    So this exercise is rather artificial unless the graphics file is basic.

    grim
  16. #9
  17. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Hehe my bad . Though it must be possible to work directly with the pixels an image since if i am remembering corectly there is a section on this in 'The Python Bible' book. I dunno PIL is the easiest option anyway.

    PyMagick is another good one but has no docs or docstrings to help you!

    Mark.
    programming language development: www.netytan.com Hula

  18. #10
  19. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    FYI:
    This link details the structure of a BMP file.
    http://www.fortunecity.com/skyscrape.../bmpffrmt.html
    If would not be difficult to manipulate the file using standard python.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    12
    Rep Power
    0
    Hi all - thanks for the info - I should have been more specific in that I want to manipulate "raw" image files - that is, files that do not have a header, but simply contain x bytes = rows * cols * bytes_per_pixel. The reason for reading into an array is that I am doing some calculations which requires the spatial relationships of pixels to be maintained.

    Anyways, thanks for all the suggestions - I am reading up on pil - that might do the job.

    Thanks again.

    AD

IMN logo majestic logo threadwatch logo seochat tools logo