Search code examples
sql-serverwindowsvarbinary

"Parameter is not valid" when using Image.fromStream method


I am struggling for hours now with this issue.

If result = Windows.Forms.DialogResult.OK Then
  Dim path As String = OpenFileDialog1.FileName
  Dim img As Image = Image.FromFile(path)
  Using mStream As New MemoryStream()
    img.Save(mStream, img.RawFormat)
    Dim bArr As Byte() = mStream.ToArray()
  End Using
  Dim params As New List(Of SqlParameter)
  params.Add(New SqlParameter("@Image", bArr))
  CallSP("UpdateImageSP", params)
End If

This will actually update the database, in a varbinary column, with the value: 0x89504E470D0A1A0A0000000D49484452000004120000041208060000001258D9C6000000017352474200AECE1CE900000004

Time to retrieve the image & show it in a picturebox:

Dim dtIcon As DataTable = DataTableGet("getImageSP")
If dtIcon IsNot Nothing AndAlso Not dtIcon.Rows(0)("Image") Is DBNull.Value Then
  Dim imageData As Byte() = DirectCast(dtIcon.Rows(0)("Image"), Byte())
  If imageData.Length > 0 Then
    Using mStream As New MemoryStream(imageData)
      Dim x As Image = Image.FromStream(mStream) --<--ERROR HERE !!
    End Using
    PictureBox1.BackgroundImage = x
  End If
End If

The error is "An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll Additional information: Parameter is not valid."

I've tried several samples of code that I found, the result was always this one. Anyone knows what's the problem here?


Solution

  • The image could be getting saved incorrectly when uploading to the database, or you could have an issue converting it back.

    One thing I would do is declare the type of your byte array going to SQL:

    params.Add(New SqlParameter("@Image", bArr, SqlDbType.VarBinary,-1))
    

    When loading the image to the database, you are not using the data as an image type. It would be easier to get the binary data using File.ReadAllBytes:

    Dim bArr As Byte()
    bArr = File.ReadAllBytes(path)
    

    Also, you can test to confirm that the saved data from the database looks correct by trying save it to disk instead of loading into a picturebox. If you cannot open it as an image there is something wrong with the saved data:

    Dim stream As New FileStream([Some Test Path], FileMode.Create, FileAccess.Write)
    stream.Write(imageData, 0, imageData.Length)
    stream.Close()