Results 1 to 38 of 38

Thread: [RESOLVED] How to read a binary file into 2D array

  1. #1

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Resolved [RESOLVED] How to read a binary file into 2D array

    Hi guys,
    I was wondering if you could help me on reading a binary file into 2D array. I have an image that has dimension of (100,100). I am using FileStream class. When I run the code I get EndOfStreamException error at line 44. I have pasted the for loop section of the code below.

    Code:
    For x = 0 To 99
                For y = 0 To 99
                    byteRead1(x, y) = br1.ReadByte ' line 44 (exception thrown here)
                Next y
            Next x
    Any help will be appreciated.

  2. #2
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: How to read a binary file into 2D array

    for what reason would you want to read a binary file into a 2d array ? There is no good reason for doing that. Explain what you are trying to do and i'm sure someone will be able to help you

  3. #3
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    May be to 'quickload' an image by loading the bytes directly? Not sure

    The only reason this doesn't work must be in the image file itself. If you are loading a .png or .jpg image for example, it contains compression. The same counts for the .bmp image, since it contains an header. Loading image files like this is probably not possible, unless the image is stored in raw byte data which I doubt.

  4. #4

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    The image I am using has raw bytes and does not include header or something else. I want to load the image pixel values into 2D array so that I could be able to access a pixel's values using (x,y).

  5. #5
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: How to read a binary file into 2D array

    Can you post the image file you're trying to load with that loop?
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  6. #6
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    Safety method: calculates the amount of pixels used (amount of bytes) and takes the square root lower bound for x and y values:
    Code:
            Dim XY As Integer = Math.Floor(Math.Sqrt(br1.BaseStream.Length)) - 1
            For x = 0 To XY
                For y = 0 To XY
                    byteRead1(x, y) = br1.ReadByte
                Next y
            Next x

  7. #7

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    I have attached the image as you requested...

    Quote Originally Posted by ntg View Post
    Can you post the image file you're trying to load with that loop?
    Attached Images Attached Images  

  8. #8

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Thanks for your reply but what if the image is not square? Lets say the image is rectangular. Then what?

    Quote Originally Posted by bergerkiller View Post
    Safety method: calculates the amount of pixels used (amount of bytes) and takes the square root lower bound for x and y values:
    Code:
            Dim XY As Integer = Math.Floor(Math.Sqrt(br1.BaseStream.Length)) - 1
            For x = 0 To XY
                For y = 0 To XY
                    byteRead1(x, y) = br1.ReadByte
                Next y
            Next x

  9. #9
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    Then you would not know the dimensions any ways. I recommend building in a simple header to your custom image format:
    <short value indicating width>
    <short value indicating height>
    For x As Integer = 0 To Width - 1
    For y As Integer = 0 To Height - 1
    Write byte color (x/y)
    Next
    Next
    Make the y-loop on the outside to save in horizontal lines, instead of vertical as it is now.

  10. #10
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: How to read a binary file into 2D array

    I don't think this has anything to do with the image. Are you are reusing an existing filestream? If so, you should either declare it as a New FileStream just before the loop, or you can reset it like this:
    Code:
         br1.Seek(0, SeekOrigin.Begin)
    Then you should check you are not mistaken in the stream length:
    Code:
     
         Dim Length = CType(br1.Length, Integer)
    BB

  11. #11

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    gyggggggg

    Quote Originally Posted by cs_tx_usa View Post
    Thanks for your reply but what if the image is not square? Lets say the image is rectangular. Then what?

  12. #12

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Unfortunately, it still gives the same error message EndOfStreamException saying that "Unable to read beyond the end of the stream"

    Quote Originally Posted by bergerkiller View Post
    Safety method: calculates the amount of pixels used (amount of bytes) and takes the square root lower bound for x and y values:
    Code:
            Dim XY As Integer = Math.Floor(Math.Sqrt(br1.BaseStream.Length)) - 1
            For x = 0 To XY
                For y = 0 To XY
                    byteRead1(x, y) = br1.ReadByte
                Next y
            Next x

  13. #13

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    No, I am not reusing the filestream.

    Quote Originally Posted by boops boops View Post
    I don't think this has anything to do with the image. Are you are reusing an existing filestream? If so, you should either declare it as a New FileStream just before the loop, or you can reset it like this:
    Code:
         br1.Seek(0, SeekOrigin.Begin)
    Then you should check you are not mistaken in the stream length:
    Code:
     
         Dim Length = CType(br1.Length, Integer)
    BB

  14. #14
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: How to read a binary file into 2D array

    Quote Originally Posted by cs_tx_usa View Post
    No, I am not reusing the filestream.
    OK, so what do you get for the FileStream length before you enter the loop?

  15. #15
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: How to read a binary file into 2D array

    I'm lost here. Your read loop reads raw bytes. The image is a GIF file and a single byte does not correspond to a pixel because GIF uses LZW compression, that's why instead of the image taking up 100x100 = 10000 bytes of space it only uses 437 bytes.

    I feel pretty certain that this isn't the issue here and I've misunderstood the problem.
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  16. #16
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    I said the same thing before, also confused of the file format he is using.

  17. #17
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: How to read a binary file into 2D array

    Yeah, the posted image is a GIF and it can't be handled as a plain stream of bytes.
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  18. #18
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    But the image reminds me of the image pathfinding thread, so I believe he posted the "visual representation" of the image, not the actual file containing the bytes. If this is the case, please upload the real image file (not the visual representation) you try to load.

  19. #19
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: How to read a binary file into 2D array

    It's the test image cs_tx_usa is using. He has turned that into a custom image file format which he can't even read himself yet, so there is not much point in posting that as an image to the forum. The error tells us the filestream isn't long enough for the loop (given that it is being read from the beginning). So all we need to know for the moment is how long the file is in bytes (my guess: 1,250).

    If the file were readable but giving garbage, there might be some point in looking at it. But then it would be more useful to see the encoding routine as well as the decoding.

    BB

  20. #20

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Ok guys, the image I have attached on my previous post has only two color index values (0 and 1):

    black pixels have a value of 0
    white pixels have a value of 1

    What I would like to do is that I want to read those pixel values (0s and 1s) into 2-dimensional array. The image has 100x100 (10,000 pixels) and I would like to load those values into 2D array of 100 rows and 100 columns.

    I would appreciate it if you could show me the way to accomplish this problem.

  21. #21

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    I don't know why but I get the file length as 437...

    Quote Originally Posted by boops boops View Post
    OK, so what do you get for the FileStream length before you enter the loop?

  22. #22

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Hmm I am confused here too because you are right and I get 437 as file length. Ok then what I should use to read the values that are stored in each pixel in a GIF file?

    Quote Originally Posted by ntg View Post
    I'm lost here. Your read loop reads raw bytes. The image is a GIF file and a single byte does not correspond to a pixel because GIF uses LZW compression, that's why instead of the image taking up 100x100 = 10000 bytes of space it only uses 437 bytes.

    I feel pretty certain that this isn't the issue here and I've misunderstood the problem.

  23. #23

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Bergerkiller, what image format should I use in order to get the values in each pixel? TIFF? or 8 bit greyscale GIF? or what?

    Quote Originally Posted by bergerkiller View Post
    I said the same thing before, also confused of the file format he is using.

  24. #24
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    A CUSTOM format. You can't use the Image class at all.

    The first step is converting your current Image format to a data byte array:
    Code:
            Dim img As Bitmap = New Bitmap(32, 32) 'load it here
            Dim data(img.Width - 1, img.Height - 1) As Byte
            For x = 0 To img.Width - 1
                For y = 0 To img.Height - 1
                    With img.GetPixel(x, y)
                        If .R < 128 And .G < 128 And .B < 128 Then
                            'black value
                            data(x, y) = 0
                        Else
                            'white value
                            data(x, y) = 1
                        End If
                    End With
                Next
            Next
            '===================================
    This method is a bit slow (uses GetPixel), but since it only has to run one time it is no issue. Next you save the byte data to a file.
    Code:
            Dim f As New IO.FileStream("Filetosaveto.cif", IO.FileMode.OpenOrCreate, IO.FileAccess.Write)
            Dim b As New IO.BinaryWriter(f)
            'header
            b.Write(img.Width)
            b.Write(img.Height)
            'data, horizontal rows
            For y As Integer = 0 To img.Height - 1
                For x As Integer = 0 To img.Width - 1
                    b.Write(data(x, y))
                Next
            Next
            b.Close()
            f.Close()
            '===================================
    "cif" stands for "custom image format".

    Now you have a file. If your image is 100x100, it will contain 100^2 + 4*2 bytes = 10008 bytes. (an integer is a length of 4 bytes)

    Now time to load it back into a multidimensional array:
    Code:
            Dim f As New IO.FileStream("Filetosaveto.cif", IO.FileMode.Open, IO.FileAccess.Read)
            Dim b As New IO.BinaryReader(f)
            Dim width As Integer = b.ReadInt32()
            Dim height As Integer = b.ReadInt32()
            Dim data(width - 1, height - 1) As Byte
            For y As Integer = 0 To height - 1
                For x As Integer = 0 To width - 1
                    data(x, y) = b.ReadByte
                Next
            Next
            b.Close()
            f.Close()
            '====================================
    Additionally, for a final test, you could do the reverse of GetPixel again (use SetPixel) and generate a new Bitmap.

    Please note that you only have to store a single bit per pixel, so basically you could set 8 bits in a single byte. This is done using bit shifting.
    The format of the image will be 8x as small, but it will be a bit harder to load and save images. Plus your image must be a size with 8 as base number:
    8, 16, 24, 32, 40, 48, 56, etc.
    I left it out to keep this all simple.

  25. #25
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: How to read a binary file into 2D array

    Good help there bergerkiller.
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  26. #26
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    Thanks.

  27. #27

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Thank you, bergerkiller, for your help with the details. I do appreciate it.

  28. #28
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    Do you want to go into "compression"? You could make the size of the image 8x as small if you were to store 8 pixels in a single byte.

    Made a simple "BPixel" structure that can hold 8 boolean values and converts them into a byte, and can get boolean values back.

    Code:
        Public Structure BPixel
            Sub New(ByVal eigthvalues As Byte)
                Me._value = eigthvalues
            End Sub
            Shared Widening Operator CType(ByVal b As BPixel) As Byte
                Return b._value
            End Operator
            Private _value As Byte
            Public Property Pixels() As Boolean()
                Get
                    Dim rval(7) As Boolean
                    For i As Integer = 0 To 7
                        rval(i) = Me.Pixels(i)
                    Next
                    Return rval
                End Get
                Set(ByVal value() As Boolean)
                    Me._value = 0
                    For i As Integer = 0 To 7
                        If value(i) Then Me._value += 2 ^ i
                    Next
                End Set
            End Property
            Public Property Pixels(ByVal index As Integer) As Boolean
                Get
                    Return (Me._value And 2 ^ index) = 2 ^ index
                End Get
                Set(ByVal value As Boolean)
                    If Pixels(index) <> value Then
                        If value = True Then Me._value += 2 ^ index Else Me._value -= 2 ^ index
                    End If
                End Set
            End Property
        End Structure

  29. #29

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Hi Bergerkiller,
    the TIFF image I am trying to read has 1170lines and 675rows and in total of 1,968,821 bytes... But the code below reads only 789,750 bytes of it...
    Code:
    Dim data(width - 1, height - 1) As Byte
            Dim output(width - 1, height - 1) As Byte
            Dim x As Integer
            Dim y As Integer
            For y = 0 To height - 1
                For x = 0 To width - 1
                    data(x, y) = br1.ReadByte
                    output(x, y) = data(x, y)
                    bw.Write(output(x, y))
                Next
            Next
          
            s1.Close()
            s3.Close()
    I think for next loop does not work for 2D arrays during reading and writing to files. Do you have any idea what to do?

  30. #30
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: How to read a binary file into 2D array

    That is pretty obvious, 1170 * 675 = 789750. As I said before, you can not load regular images, only raw data. The images must be loaded using Image.load() and loading is done by the system (codec).

    If you REALLY want to do this directly, load the file using Image.load and save it in raw data to a new file.

    Just to make sure you understand:
    1. Tiff, Bmp, Jpeg, Png, etc. image format contain compression. You can not load these images by looping the bytes
    2. Only RAW image data (every pixel in a single byte) can be looped
    3. To convert Image to RAW data, Load the image and use GetPixel on a multidimensional byte array. Then save it in raw form.

  31. #31
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: How to read a binary file into 2D array

    I think that reading a bit about image formats may help.
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  32. #32

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Thank you, Bergerkiller.. You made your point very clear )

    Quote Originally Posted by bergerkiller View Post
    That is pretty obvious, 1170 * 675 = 789750. As I said before, you can not load regular images, only raw data. The images must be loaded using Image.load() and loading is done by the system (codec).

    If you REALLY want to do this directly, load the file using Image.load and save it in raw data to a new file.

    Just to make sure you understand:

  33. #33

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Thanks ntg for the link.

    Quote Originally Posted by ntg View Post
    I think that reading a bit about image formats may help.

  34. #34

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: How to read a binary file into 2D array

    Hi bergerkiller. Thanks again for all your help. Now that bytes are loaded into 2D array how can I access it from another method. Bytes are loaded into 2D array in form1_load subroutine but I would like to access the elements of this array from another method.

    Quote Originally Posted by bergerkiller View Post
    That is pretty obvious, 1170 * 675 = 789750. As I said before, you can not load regular images, only raw data. The images must be loaded using Image.load() and loading is done by the system (codec).

    If you REALLY want to do this directly, load the file using Image.load and save it in raw data to a new file.

    Just to make sure you understand:

  35. #35
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: [RESOLVED] How to read a binary file into 2D array

    Make the bytes global.

    Code:
    Public Data()() As Byte
    
    <sub load()>
        Dim loadedbytes(32, 32) As Byte
        ...
        Data = loadedbytes
    End Sub

  36. #36

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: [RESOLVED] How to read a binary file into 2D array

    Hi bergerkiller,
    Should I set the global array empty? like:

    Public Data(,) As Byte

    or should I set it like this?

    Public Data(width-1,height-1) As Byte

    Thanks...


    Quote Originally Posted by bergerkiller View Post
    Make the bytes global.

    Code:
    Public Data()() As Byte
    
    <sub load()>
        Dim loadedbytes(32, 32) As Byte
        ...
        Data = loadedbytes
    End Sub

  37. #37
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: [RESOLVED] How to read a binary file into 2D array

    I guess its best to keep it empty:
    Code:
    Public Data()() As Byte
    If you define bounds it will only overwrite it later any ways. You can not (easily) change the dimensions of a multi dimensional array, so best is to set the Data member directly, like so:
    Code:
    Dim NewData(width - 1, height - 1) As Byte
    For ---
       For ---
           NewData(x,y) = r.ReadByte()
       Next
    Next
    Data = NewData
    Another minor thing: you may want to read all bytes of a single horizontal row in one go.
    Code:
    For y As Integer = 0 To Height - 1
        r.Read(NewData(y), 0, Width)
    Next
    Or something like that. Not sure if it is faster, but it would reduce the amount of traffic going to the processor.

  38. #38

    Thread Starter
    Lively Member cs_tx_usa's Avatar
    Join Date
    Dec 2007
    Posts
    98

    Re: [RESOLVED] How to read a binary file into 2D array

    Thanks bergerkiller. I do appreciate your help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width