Results 1 to 22 of 22

Thread: [RESOLVED] MSCOMM : Save received data as a Bitmap file

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Resolved [RESOLVED] MSCOMM : Save received data as a Bitmap file

    I coded an app which connects to a device through serial port. The device sends some values (numbers) followed by a bitmap image formed of 11518 characters/bytes starting with 'BM' header of course.

    The problem is that the bitmap file I create from these 11518 characters (stored in rs232Data variable of string type) is corrupted!!
    I am using the following code:
    Code:
    Open "D:\Test.bmp" For Binary As #1
    Put #1, , rs232Data
    Close #1
    P.S : I have a similar app connected to a different device which I use the same code above but after decoding the Base64 data received and it works just fine, the current device does send normal ASCII (0-255) characters.

    I do appreciate if someone can help.
    Last edited by labmany; Oct 20th, 2017 at 06:45 AM.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    You are probably using Strings and Text mode to receive the serial port data. That will distort the data. Trying using Byte arrays and Binary mode.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Thanks dilettante, but I am not sure how to implement a byte array which stores the whole data stream till it hits a ETX character!
    I mean the whole data will not be delivered at once so the OnComm event will be fired a few times and every time the byte array will be overwritten or am I missing something?!!

    Code:
    Dim rs232Data() As Byte
    
    Private Sub MSComm1_OnComm()
    
        rs232Data = MSComm1.Input
        
        If rs232Data(UBound(rs232Data)) = Chr$(3) Then Call Finished
    
    End Sub

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    Another option is to simply open a file and write the byte(s) returned by the input directly to the file. When ETX is received, close the file. Air code follows...
    Code:
    Dim hFile As Integer, rs232Data() As Byte
    hFile = FreeFile()
    Open "C:\...\rs232_uniqueKey.bmp" For Binary As #hFile
    
    Private Sub MSComm1_OnComm()
    
        rs232Data = MSComm1.Input
        If hFile = 0 Then Exit Sub    
    
        If rs232Data(UBound(rs232Data)) = Chr$(3) Then 
            If UBound(rs232Data) > LBound(rs232Data) Then ' test against a 1 byte array
                ReDim Preserve rs232Data(LBound(rs232Data) To UBound(rs232Data)-1)
                Put #hFile, , rs232Data()
            End If
            Close #hFile
            hFile = 0  ' can be checked in form unload or elsewhere to see if it's still open or closed
            Call Finished
        Else
            Put #hFile, , rs232Data()
        End If
    
    End Sub
    Edited: If aborting while receiving data, close the handle outside of the above routine and delete the file.
    Last edited by LaVolpe; Oct 21st, 2017 at 09:07 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Thanks Lavolpe, I will consider this.

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    You can't delimit the stream using &H03 ETX because that's a valid byte value in any binary data.

    These sorts of things usually either encode the binary as text, use an escape scheme, or most often use a length header.

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    Quote Originally Posted by dilettante View Post
    You can't delimit the stream using &H03 ETX because that's a valid byte value in any binary data.
    Excellent point. The value 0x03 can be part of the bitmap data/pixel info. Though one can still get through this. When enough bytes received 54+ (that should be the file header + minimal bitmap info header), then one can calculate how many bytes are required for the entire bitmap. Once that has been reached, close out the file and/or truncate the file as needed.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    He's back to needing a stream assembly technique or clever code that extracts the length data on the fly.

    Keep in mind the data may well arrive in bursts of 1 to many bytes for each comEvReceive event.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    Or just use the file as the assembly technique and periodically check it (from within that same routine). Keeping track of number of bytes received would be a start. Once byte count reached 54+, needed byte count (for complete file) can be calculated and known.

    Calculating where in the file the bitmap data actually ends isn't that difficult. Once the complete data is there, can simply strip out the needed data to a another, true, bitmap file. Of course, without some sort of packet telling how many bytes are expected, calculating needed bytes relies on the bitmap file/info headers being properly filled in. The size of the entire bitmap can be calculated from both the file header (1st 14 bytes where there's an actual field for that value) and the bitmap info header (next 40+ bytes) that will require in-depth knowledge of the various bitmap formats/header versions

    Edited: pseudo-code
    Code:
    get bytes from comm
    write bytes to data file
    increment byte count: count = existing count + new bytes just received
    If byte count = > 54 then calculate total bytes needed for bitmap
    If byte count = > total needed byte count, extract data from data file to a new bitmap file
    rinse & repeat
    Last edited by LaVolpe; Oct 21st, 2017 at 01:38 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    Using files for this feels like linking several 1940s washing machines together with belts. If you can't use one of the many "binary string builder" classes that have been published here there is always the handy ADO Stream object.

  11. #11
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    Quote Originally Posted by dilettante View Post
    Using files for this feels like linking several 1940s washing machines together with belts.
    At least you can fix those

    Point taken and I'd second the notion of an ADO stream. Regardless of the collection method, I think the logic I provided, in post #9 not post #3, should work unless the OP wants to hope that whenever the last byte in the current burst is 0x03, it also happens to be the end of the stream.
    Last edited by LaVolpe; Oct 21st, 2017 at 02:28 PM. Reason: clarification of which logic
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    Well it seems very flawed to have that ETX at the end, but if it is going to be sent after the image data he should be sure to consume and discard the extra byte if more data is to follow.

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Thank you very much guys for your help.

    Actually, here is an example of the data stream

    {STX}nnnnnnnnDDMMYYYYnnn|nnn|nnn|nnn|nnn|nnnIM1BMP11518BMxxx...xxxIM2BMP11518BMxxx...xxxIM3BMPBMxxx. ..xxx{ETX}

    Where:
    {STX} = Chr$(2)
    {ETX} = Chr$(3)
    n = numbers from 0 to 9
    DDMMYYYY = Date
    IM1BMP11518 = IM1 first image of BMP type with length of 11518 bytes.
    IM2BMP11518 = IM2 first image of BMP type with length of 11518 bytes.
    IM3BMP11518 = IM3 first image of BMP type with length of 11518 bytes.
    xxx...xxx = 11518 bytes adding "BM" to the start of them

    The whole data stream is fixed length every time the device send it, I parse the numeric values, get the start of the first BMP file using Instr(rs232Data,"IM1BMP") + 11 and the length of it is just 11518 bytes long and save it as binary file, get the second one, the third one and I am done.
    All numeric values are perfect, Bitmap files are corrupted!!!
    Last edited by labmany; Oct 21st, 2017 at 09:08 PM.

  14. #14
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    Zip and post one of your streams saved to file, if you saved it from a binary stream. We can take a look see.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    I tried the binary mode but all I get is ??????????
    So I reverted back to text mode.

    I will zip and post as soon as I go to work, it is 5:00AM right now

  16. #16
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    Why would you expect binary data to look like plain text?

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Well, I found a file which I copied on my flash drive, here we go:
    Attached Files Attached Files

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Quote Originally Posted by dilettante View Post
    Why would you expect binary data to look like plain text?
    I do not

  19. #19
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: MSCOMM : Save received data as a Bitmap file

    The most straightforward way to handle this has already been described.

    Accept the data as binary, extract any ANSI substrings you need like your "numbers" and convert them. Write the segments containing a bitmap to disk.

    Text mode converts each Byte or Bytes received to Unicode String values. It was only meant to be used when you receive strictly ASCII data.


    As far as I can see your data looks fine. Clearly as it was poured "from glass to glass" multiple times converting to Unicode and back to ANSI when writing to disk... you got lucky. Mainly because there were no locale changes between conversions. However even for the same locale some bit patterns might not survive without distortion.

    But it looks like it should be ok if you separate out the bitmap segments and write those to disk separately. I wouldn't do it, but it may work most of the time for you.

  20. #20
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: MSCOMM : Save received data as a Bitmap file

    I does appear you are interpreting the stream correctly. If extracting from the cached data the byte where "BM" (not BMP) is found and extracting the 11518 bytes, it is a complete, valid bitmap. Looks like a graph/chart. I did look at the 1st bitmap a bit closely to verify the 11518 is correct and it was. I don't know if that value came from the bitmap file header (included in the stream) or not. If it did, hopefully all of them are correct if you are going to rely on it. However, if all your bitmaps are 16 color, 150x150 then the size of each 'file' should be the same.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,207

    Re: MSCOMM : Save received data as a Bitmap file

    Quote Originally Posted by labmany View Post
    I do not
    Good, below is a routine, which is able to parse-out the contained Bitmap-Parts from your incoming ByteArray-Data
    (for the demo, your posted file-content was used, after placing it in "c:\temp\test.txt" - the resulting Bitmap-Files are also placed there):

    Code:
    Option Explicit
    
    Private Sub Form_Load()
      Dim B() As Byte
      ReadWriteBytes "C:\temp\test.txt", B, True 'read the Input-ByteArray from disk
      
      ParseBytes B 'make an attempt to parse what's in there, BitMap-wise
    End Sub
    
    Private Sub ReadWriteBytes(FileName, B() As Byte, ByVal ReadThem As Boolean)
    Dim FNr As Long
        FNr = FreeFile: Open FileName For Binary As FNr
          If ReadThem Then ReDim B(0 To LOF(FNr) - 1): Get FNr, , B Else Put FNr, , B
        Close FNr
    End Sub
    
    Private Sub ParseBytes(B() As Byte)
      Dim i As Long, j As Long, L1 As Long, L2 As Long, BMP() As Byte
      For i = 0 To UBound(B) - 20
        If B(i) = 66 And B(i + 1) = 77 And B(i + 2) = 80 Then
          L1 = 0: L2 = 0
          For j = i + 3 To i + 13
            If B(j) = 66 And B(j + 1) = 77 Then
              L1 = B(j + 2) + 256& * B(j + 3) + 65536 * B(j + 4)
              Exit For
            End If
          Next
          If L1 > 0 Then
             For j = i + 3 To j - 1: L2 = L2 * 10 + B(j) - 48: Next
             If L1 = L2 And j + L1 <= UBound(B) Then
               i = j: ReDim BMP(0 To L1 - 1)
               For j = 0 To UBound(BMP): BMP(j) = B(i + j): Next
               'the BMP-ByteArray is now filled... (here we simply write it to disk)
               ReadWriteBytes "C:\temp\BitmapAtOffs" & i & ".bmp", BMP, False
             End If
          End If
        End If
      Next
    End Sub
    The 3 Bitmaps are also written to "c:\temp\..." - here is the last of the 3 Bitmaps which were found:


    HTH

    Olaf

  22. #22

    Thread Starter
    Addicted Member
    Join Date
    Sep 2015
    Posts
    225

    Re: MSCOMM : Save received data as a Bitmap file

    Quote Originally Posted by Schmidt View Post
    Good, below is a routine, which is able to parse-out the contained Bitmap-Parts from your incoming ByteArray-Data
    (for the demo, your posted file-content was used, after placing it in "c:\temp\test.txt" - the resulting Bitmap-Files are also placed there):

    Code:
    Option Explicit
    
    Private Sub Form_Load()
      Dim B() As Byte
      ReadWriteBytes "C:\temp\test.txt", B, True 'read the Input-ByteArray from disk
      
      ParseBytes B 'make an attempt to parse what's in there, BitMap-wise
    End Sub
    
    Private Sub ReadWriteBytes(FileName, B() As Byte, ByVal ReadThem As Boolean)
    Dim FNr As Long
        FNr = FreeFile: Open FileName For Binary As FNr
          If ReadThem Then ReDim B(0 To LOF(FNr) - 1): Get FNr, , B Else Put FNr, , B
        Close FNr
    End Sub
    
    Private Sub ParseBytes(B() As Byte)
      Dim i As Long, j As Long, L1 As Long, L2 As Long, BMP() As Byte
      For i = 0 To UBound(B) - 20
        If B(i) = 66 And B(i + 1) = 77 And B(i + 2) = 80 Then
          L1 = 0: L2 = 0
          For j = i + 3 To i + 13
            If B(j) = 66 And B(j + 1) = 77 Then
              L1 = B(j + 2) + 256& * B(j + 3) + 65536 * B(j + 4)
              Exit For
            End If
          Next
          If L1 > 0 Then
             For j = i + 3 To j - 1: L2 = L2 * 10 + B(j) - 48: Next
             If L1 = L2 And j + L1 <= UBound(B) Then
               i = j: ReDim BMP(0 To L1 - 1)
               For j = 0 To UBound(BMP): BMP(j) = B(i + j): Next
               'the BMP-ByteArray is now filled... (here we simply write it to disk)
               ReadWriteBytes "C:\temp\BitmapAtOffs" & i & ".bmp", BMP, False
             End If
          End If
        End If
      Next
    End Sub
    The 3 Bitmaps are also written to "c:\temp\..." - here is the last of the 3 Bitmaps which were found:


    HTH

    Olaf
    Thanks Olaf, you made my day

    By the way, I can not wait to see your vbRichClient compiler

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