MemoryStream bug?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Don

    #1

    MemoryStream bug?

    When I run the following code, the MemoryStream's Position is always set to
    762 instead of 0, which is what I would expect:


    Dim bmp As Image
    Dim ms As MemoryStream

    bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
    ms = New MemoryStream
    bmp.Save(ms, bmp.RawFormat)
    Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
    ms.Close()


    This is happening on two different computers for me. Does this happen to
    anyone else? Is there a reason why the memory stream's position is set to
    762 instead of 0? Or is it proper practice to always manually set stream
    positions to zero when first creating them?

    - Don


  • Jay B. Harlow [MVP - Outlook]

    #2
    Re: MemoryStream bug?

    Don,
    | Does this happen to
    | anyone else?
    Yes

    | Is there a reason why the memory stream's position is set to
    | 762 instead of 0?
    Yes, as I suspect that the bmp.Save statement wrote 762 bytes of information
    to the stream.

    | bmp.Save(ms, bmp.RawFormat)
    | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)

    Seeing as Image.Save is writing information to the stream, I would expect
    the stream's position to actually move, so when I write more information to
    the stream the stream is positioned to a "writable" position...

    | Or is it proper practice to always manually set stream
    | positions to zero when first creating them?
    No, I don't set the position when first creating them.

    Hope this helps
    Jay

    "Don" <unknown@oblivi on.com> wrote in message
    news:kwCye.1872 153$6l.739353@p d7tw2no...
    | When I run the following code, the MemoryStream's Position is always set
    to
    | 762 instead of 0, which is what I would expect:
    |
    |
    | Dim bmp As Image
    | Dim ms As MemoryStream
    |
    | bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
    | ms = New MemoryStream
    | bmp.Save(ms, bmp.RawFormat)
    | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
    | ms.Close()
    |
    |
    | This is happening on two different computers for me. Does this happen to
    | anyone else? Is there a reason why the memory stream's position is set to
    | 762 instead of 0? Or is it proper practice to always manually set stream
    | positions to zero when first creating them?
    |
    | - Don
    |
    |


    Comment

    • Herfried K. Wagner [MVP]

      #3
      Re: MemoryStream bug?

      "Don" <unknown@oblivi on.com> schrieb:[color=blue]
      > bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
      > ms = New MemoryStream
      > bmp.Save(ms, bmp.RawFormat)
      > Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
      > ms.Close()
      >
      >
      > This is happening on two different computers for me. Does this happen to
      > anyone else? Is there a reason why the memory stream's position is set to
      > 762 instead of 0?[/color]

      I assume it's caused by writing the data to the stream. By writing data the
      input position will be incremented by the number of bytes written to the
      stream.

      --
      M S Herfried K. Wagner
      M V P <URL:http://dotnet.mvps.org/>
      V B <URL:http://classicvb.org/petition/>

      Comment

      • Don

        #4
        Re: MemoryStream bug?

        I've tried this with two different sized images, both about 30K in size, and
        the Position was initialized to 762 in both cases. Using a hex editor I
        determined that this was exactly 762 bytes into the actual image. It seems
        like an arbitrary position in the middle of the stream.

        - Don


        "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
        news:uaKmoLbgFH A.2880@TK2MSFTN GP14.phx.gbl...[color=blue]
        > "Don" <unknown@oblivi on.com> schrieb:[color=green]
        > > bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
        > > ms = New MemoryStream
        > > bmp.Save(ms, bmp.RawFormat)
        > > Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
        > > ms.Close()
        > >
        > >
        > > This is happening on two different computers for me. Does this happen[/color][/color]
        to[color=blue][color=green]
        > > anyone else? Is there a reason why the memory stream's position is set[/color][/color]
        to[color=blue][color=green]
        > > 762 instead of 0?[/color]
        >
        > I assume it's caused by writing the data to the stream. By writing data[/color]
        the[color=blue]
        > input position will be incremented by the number of bytes written to the
        > stream.
        >
        > --
        > M S Herfried K. Wagner
        > M V P <URL:http://dotnet.mvps.org/>
        > V B <URL:http://classicvb.org/petition/>
        >[/color]


        Comment

        • Don

          #5
          Re: MemoryStream bug?


          "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP @msn.com> wrote in message
          news:OSclqIbgFH A.3936@TK2MSFTN GP10.phx.gbl...[color=blue]
          > Don,
          > | Does this happen to
          > | anyone else?
          > Yes[/color]

          Have you tried it? What were the results?

          [color=blue]
          > | Is there a reason why the memory stream's position is set to
          > | 762 instead of 0?
          > Yes, as I suspect that the bmp.Save statement wrote 762 bytes of
          > information to the stream.[/color]

          Nope. The image that was loaded into the memory stream was about 30,000
          bytes.

          [color=blue]
          >
          > | bmp.Save(ms, bmp.RawFormat)
          > | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
          >
          > Seeing as Image.Save is writing information to the stream, I would
          > expect the stream's position to actually move, so when I write more
          > information to the stream the stream is positioned to a "writable"
          > position...[/color]

          That would make sense if the Position also equalled the length of the image
          stored into the stream, but it doesn't.

          [color=blue]
          > | Or is it proper practice to always manually set stream
          > | positions to zero when first creating them?
          >
          > No, I don't set the position when first creating them.[/color]

          I didn't do this either, at first, and it always resulted in a corrupt image
          when I tried to make one from the stream because the first 762 bytes were
          chopped off.

          - Don


          Comment

          • Cor Ligthert [MVP]

            #6
            Re: MemoryStream bug?

            Don,

            I only can say that I don't do the way you do.

            Have a look at this sample that I made yesterday for somebody else.

            \\\Needs two pictureboxes and a button on a form
            Private Sub Form1_Load(ByVa l sender As _
            System.Object, ByVal e As System.EventArg s) Handles MyBase.Load
            Dim fo As New OpenFileDialog
            If fo.ShowDialog = DialogResult.OK Then
            Dim fs As New IO.FileStream(f o.FileName, _
            IO.FileMode.Ope n)
            Dim br As New IO.BinaryReader (fs)
            Dim abyt As Byte()
            abyt = br.ReadBytes(CI nt(fs.Length))
            br.Close()
            'just to show the sample without a fileread error
            Dim ms As New IO.MemoryStream (abyt)
            Me.PictureBox1. Image = Image.FromStrea m(ms)
            End If
            End Sub
            Private Sub Button1_Click(B yVal sender As System.Object, _
            ByVal e As System.EventArg s) Handles Button1.Click
            Dim abyt As Byte()
            Dim ms As New IO.MemoryStream
            PictureBox1.Ima ge.Save(ms, Imaging.ImageFo rmat.Bmp)
            abyt = ms.GetBuffer
            Dim ms2 As New IO.MemoryStream (abyt)
            Me.PictureBox2. Image = Image.FromStrea m(ms2)
            Me.PictureBox1. Image = Nothing
            End Sub
            ////
            I hope this helps a little bit?

            Cor


            Comment

            • Jay B. Harlow [MVP - Outlook]

              #7
              Re: MemoryStream bug?

              Don,
              | Have you tried it? What were the results?
              I have written to a memory stream lots of times, each time I write to it,
              the Position property moved the number of bytes that I wrote. Ergo the point
              of my yes!

              I have not specifically used the Image.Save method.

              | Nope. The image that was loaded into the memory stream was about 30,000
              | bytes.
              Then obviously ms.Position needs to be about 30,000 then doesn't it! My
              point is that ms.Position will not be zero as you wrote data to the Stream.

              | That would make sense if the Position also equalled the length of the
              image
              | stored into the stream, but it doesn't.
              Ah! There's the rub! I would expect Position should equal the length of the
              image file. Oddly enough ms.Length equals the length of the image file.

              Have you looked at what is actually in the memory stream? Is only the first
              762 bytes of the image written? Has only the image header been written,
              instead of the image header & actual bit information?


              Interesting enough if start with a jpeg or save to a jpeg:

              | > | bmp.Save(ms, Imaging.ImageFo rmat.Jpeg)
              | > | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)

              Then ms.Position & ms.Length do match, so it seems to me that writing a
              Bitmap has some special quirk to it, unfortunately I don't bitmaps as much
              as I use Jpegs. Have you tried writing to a FileStream instead of a
              MemoryStream? Do you have the same problem? I see the same results with a
              FileStream or MemoryStream, which suggests the "bug" aka quirk is really in
              the Image.Save method when using ImageFormat.Bmp . A quick (very quick)
              search of support.microso ft.com has not offered any suggestions.

              Have you considered asking "down the hall" in the
              microsoft.publi c.dotnet.framew ork.drawing newsgroup about any special quirks
              on saving a Bitmap (.BMP) file?

              Hope this helps
              Jay

              "Don" <unknown@oblivi on.com> wrote in message
              news:PwQye.1876 332$6l.505694@p d7tw2no...
              |
              | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP @msn.com> wrote in message
              | news:OSclqIbgFH A.3936@TK2MSFTN GP10.phx.gbl...
              | > Don,
              | > | Does this happen to
              | > | anyone else?
              | > Yes
              |
              | Have you tried it? What were the results?
              |
              |
              | > | Is there a reason why the memory stream's position is set to
              | > | 762 instead of 0?
              | > Yes, as I suspect that the bmp.Save statement wrote 762 bytes of
              | > information to the stream.
              |
              | Nope. The image that was loaded into the memory stream was about 30,000
              | bytes.
              |
              |
              | >
              | > | bmp.Save(ms, bmp.RawFormat)
              | > | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
              | >
              | > Seeing as Image.Save is writing information to the stream, I would
              | > expect the stream's position to actually move, so when I write more
              | > information to the stream the stream is positioned to a "writable"
              | > position...
              |
              | That would make sense if the Position also equalled the length of the
              image
              | stored into the stream, but it doesn't.
              |
              |
              | > | Or is it proper practice to always manually set stream
              | > | positions to zero when first creating them?
              | >
              | > No, I don't set the position when first creating them.
              |
              | I didn't do this either, at first, and it always resulted in a corrupt
              image
              | when I tried to make one from the stream because the first 762 bytes were
              | chopped off.
              |
              | - Don
              |
              |


              Comment

              • Jay B. Harlow [MVP - Outlook]

                #8
                Re: MemoryStream bug?

                Don,
                Mystery solved!

                Its how Bitmap.Save is implemented!

                Based on the TraceStream class (below) Bitmap.Save writes rows from the end
                of the file to the beginning of the file.

                Try the following with the TraceStream class:

                Dim bmp As Image
                Dim ms As IO.MemoryStream

                bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
                ms = New IO.MemoryStream
                Dim ts As New TraceStream(ms)
                bmp.Save(ts, bmp.RawFormat)
                Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
                ms.Close()

                Notice the initial SetLength and then how the Position decreases & one "row"
                of bytes are written. Hence the Stream is left at the length of the header +
                the length of one "row" in bytes, your 762 and not the about 30,000 I would
                expect (based on your other message).


                A quick TraceStream class, it writes trace information on selected
                methods...

                ---x--- cut here ---x--- begin TraceStream.vb ---x---
                Option Strict On
                Option Explicit On

                Imports System.IO

                Public Class TraceStream
                Inherits Stream

                Private ReadOnly m_stream As Stream

                Public Sub New(ByVal stream As Stream)
                If stream Is Nothing Then Throw New ArgumentNullExc eption("stream" )
                m_stream = stream
                End Sub

                Private Sub WriteTrace(ByVa l format As String, ByVal ParamArray args()
                As Object)
                Dim message As String = String.Format(f ormat, args)
                Trace.WriteLine (message, "TraceStrea m")
                End Sub

                Public Overrides ReadOnly Property CanRead() As Boolean
                Get
                Return m_stream.CanRea d
                End Get
                End Property

                Public Overrides ReadOnly Property CanSeek() As Boolean
                Get
                Return m_stream.CanSee k
                End Get
                End Property

                Public Overrides ReadOnly Property CanWrite() As Boolean
                Get
                Return m_stream.CanWri te
                End Get
                End Property

                Public Overrides ReadOnly Property Length() As Long
                Get
                Return m_stream.Length
                End Get
                End Property

                Public Overrides Property Position() As Long
                Get
                Return m_stream.Positi on
                End Get
                Set(ByVal value As Long)
                WriteTrace("Pos ition={0}", value)
                m_stream.Positi on = value
                End Set
                End Property

                Public Overrides Sub Flush()
                WriteTrace("Flu sh")
                m_stream.Flush( )
                End Sub

                Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As
                Integer, ByVal count As Integer) As Integer
                WriteTrace("Rea d(buffer={0}, offset={1}, count={2})", buffer,
                offset, count)
                Return m_stream.Read(b uffer, offset, count)
                End Function

                Public Overrides Function Seek(ByVal offset As Long, ByVal origin As
                System.IO.SeekO rigin) As Long
                WriteTrace("See k(offset={0}, origin={1})", offset, origin)
                Return m_stream.Seek(o ffset, origin)
                End Function

                Public Overrides Sub SetLength(ByVal value As Long)
                WriteTrace("Set Length(value={0 })", value)
                m_stream.SetLen gth(value)
                End Sub

                Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As
                Integer, ByVal count As Integer)
                WriteTrace("Wri te(buffer={0}, offset={1}, count={2})", buffer,
                offset, count)
                m_stream.Write( buffer, offset, count)
                End Sub

                Public Overrides Sub WriteByte(ByVal value As Byte)
                WriteTrace("Wri teByte(value={0 })", value)
                m_stream.WriteB yte(value)
                End Sub

                End Class
                ---x--- cut here ---x--- end TraceStream.vb ---x---

                Hope this helps
                Jay

                "Don" <unknown@oblivi on.com> wrote in message
                news:kwCye.1872 153$6l.739353@p d7tw2no...
                | When I run the following code, the MemoryStream's Position is always set
                to
                | 762 instead of 0, which is what I would expect:
                |
                |
                | Dim bmp As Image
                | Dim ms As MemoryStream
                |
                | bmp = New System.Drawing. Bitmap("C:\2068 .bmp")
                | ms = New MemoryStream
                | bmp.Save(ms, bmp.RawFormat)
                | Console.WriteLi ne("MemoryStrea m Position = " & ms.Position)
                | ms.Close()
                |
                |
                | This is happening on two different computers for me. Does this happen to
                | anyone else? Is there a reason why the memory stream's position is set to
                | 762 instead of 0? Or is it proper practice to always manually set stream
                | positions to zero when first creating them?
                |
                | - Don
                |
                |


                Comment

                • joe

                  #9
                  Re: MemoryStream bug?

                  Cor Ligthert,


                  many thanks!!

                  your code is wonderful..^^
                  but I can't still solve this problem..

                  Save Image in SQL DB ----------------------------------
                  Dim picturedata as byte()
                  Dim ms As New IO.MemoryStream
                  picturebox1.Ima ge.Save(ms, System.Drawing. Imaging.ImageFo rmat.Jpeg)
                  picturedata = ms.GetBuffer

                  ....SQL process...
                  Dim myCommand As New SqlCommand(myIn sertQuery, myConnection)
                  myCommand.Comma ndText = "InsertData "
                  Dim myParm1 As SqlParameter = myCommand.Param eters.Add("@ima ge",
                  SqlDbType.image )
                  myParm1.Value = picturedata


                  Load image -----------------------------------------------
                  .....
                  if myreader.Read()

                  Dim picutredata as byte()
                  picturedata = myreader("image ")
                  Dim ms as New IO.Memorystream (picturedata)
                  pictureBox1.ima ge = image.Fromstrea m(ms) ---> argument error


                  I don't know what is a problem.. could you help me?

                  Joe


                  "Cor Ligthert [MVP]" wrote:
                  [color=blue]
                  > Don,
                  >
                  > I only can say that I don't do the way you do.
                  >
                  > Have a look at this sample that I made yesterday for somebody else.
                  >
                  > \\\Needs two pictureboxes and a button on a form
                  > Private Sub Form1_Load(ByVa l sender As _
                  > System.Object, ByVal e As System.EventArg s) Handles MyBase.Load
                  > Dim fo As New OpenFileDialog
                  > If fo.ShowDialog = DialogResult.OK Then
                  > Dim fs As New IO.FileStream(f o.FileName, _
                  > IO.FileMode.Ope n)
                  > Dim br As New IO.BinaryReader (fs)
                  > Dim abyt As Byte()
                  > abyt = br.ReadBytes(CI nt(fs.Length))
                  > br.Close()
                  > 'just to show the sample without a fileread error
                  > Dim ms As New IO.MemoryStream (abyt)
                  > Me.PictureBox1. Image = Image.FromStrea m(ms)
                  > End If
                  > End Sub
                  > Private Sub Button1_Click(B yVal sender As System.Object, _
                  > ByVal e As System.EventArg s) Handles Button1.Click
                  > Dim abyt As Byte()
                  > Dim ms As New IO.MemoryStream
                  > PictureBox1.Ima ge.Save(ms, Imaging.ImageFo rmat.Bmp)
                  > abyt = ms.GetBuffer
                  > Dim ms2 As New IO.MemoryStream (abyt)
                  > Me.PictureBox2. Image = Image.FromStrea m(ms2)
                  > Me.PictureBox1. Image = Nothing
                  > End Sub
                  > ////
                  > I hope this helps a little bit?
                  >
                  > Cor
                  >
                  >
                  >[/color]

                  Comment

                  • Cor Ligthert [MVP]

                    #10
                    Re: MemoryStream bug?

                    Joe,

                    I had to make this sample the day before yesterday, because I have a
                    standard sample for database hanlding in which I saw than that I had removed
                    the transforming from an image directly. However for your database handling
                    you can look at the original sample.

                    Try to look all around things handling this sampling as writting to disk
                    from the image and dataset. (I will probably make a more compact one from
                    this in short future).



                    I hope this helps,

                    Cor




                    Comment

                    • Don

                      #11
                      Re: MemoryStream bug?

                      Thanks!

                      - Don


                      Comment

                      • Jay B. Harlow [MVP - Outlook]

                        #12
                        Re: MemoryStream bug?

                        Cor,
                        Aren't you getting extra data at the end of the file?

                        As MemoryStream.Ge tBuffer returns the entire buffer (MemoryStream.C apacity)
                        for the MemoryStream which may contain "buffer" after the actual file end
                        (MemoryStream.L ength). Normally I use MemoryStream.To Array when I want a
                        copy of the "entire" file.

                        | abyt = ms.GetBuffer

                        Hope this helps
                        Jay

                        "Cor Ligthert [MVP]" <notmyfirstname @planet.nl> wrote in message
                        news:%23SesG5ig FHA.1148@TK2MSF TNGP12.phx.gbl. ..
                        | Don,
                        |
                        | I only can say that I don't do the way you do.
                        |
                        | Have a look at this sample that I made yesterday for somebody else.
                        |
                        | \\\Needs two pictureboxes and a button on a form
                        | Private Sub Form1_Load(ByVa l sender As _
                        | System.Object, ByVal e As System.EventArg s) Handles MyBase.Load
                        | Dim fo As New OpenFileDialog
                        | If fo.ShowDialog = DialogResult.OK Then
                        | Dim fs As New IO.FileStream(f o.FileName, _
                        | IO.FileMode.Ope n)
                        | Dim br As New IO.BinaryReader (fs)
                        | Dim abyt As Byte()
                        | abyt = br.ReadBytes(CI nt(fs.Length))
                        | br.Close()
                        | 'just to show the sample without a fileread error
                        | Dim ms As New IO.MemoryStream (abyt)
                        | Me.PictureBox1. Image = Image.FromStrea m(ms)
                        | End If
                        | End Sub
                        | Private Sub Button1_Click(B yVal sender As System.Object, _
                        | ByVal e As System.EventArg s) Handles Button1.Click
                        | Dim abyt As Byte()
                        | Dim ms As New IO.MemoryStream
                        | PictureBox1.Ima ge.Save(ms, Imaging.ImageFo rmat.Bmp)
                        | abyt = ms.GetBuffer
                        | Dim ms2 As New IO.MemoryStream (abyt)
                        | Me.PictureBox2. Image = Image.FromStrea m(ms2)
                        | Me.PictureBox1. Image = Nothing
                        | End Sub
                        | ////
                        | I hope this helps a little bit?
                        |
                        | Cor
                        |
                        |


                        Comment

                        • Cor Ligthert [MVP]

                          #13
                          Re: MemoryStream bug?

                          Jay,

                          You know that I never search long for an extra byte less or more.

                          However when I know it than I keep notice of it.

                          Therefore thanks I will check this and make changes accoording to that.

                          Cor


                          Comment

                          • Cor Ligthert [MVP]

                            #14
                            Re: MemoryStream bug?

                            Jay,

                            You are right (not that I was in doubt about that) :-)

                            It makes a big difference.



                            Thanks again

                            Cor


                            Comment

                            Working...