"参数无效"使用Image.fromStream方法时

时间:2015-11-16 16:48:27

标签: sql-server windows varbinary

我现在正在努力解决这个问题。

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

这实际上将在varbinary列中使用以下值更新数据库: 0x89504E470D0A1A0A0000000D49484452000004120000041208060000001258D9C6000000017352474200AECE1CE900000004

检索图像的时间&在图片框中显示:

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

错误是&#34;未处理的类型&#39; System.ArgumentException&#39;发生在System.Drawing.dll中 附加信息:参数无效。&#34;

我已经尝试了几个我发现的代码示例,结果总是这一个。任何人都知道这里的问题是什么?

2 个答案:

答案 0 :(得分:0)

上传到数据库时图像可能会被错误地保存,或者您可能在将其转换回来时出现问题。

我要做的一件事是将字节数组的类型声明为SQL:

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

将图像加载到数据库时,您没有将数据用作图像类型。使用File.ReadAllBytes:

获取二进制数据会更容易
Dim bArr As Byte()
bArr = File.ReadAllBytes(path)

此外,您可以通过尝试将数据保存到磁盘而不是加载到图片框中来测试以确认数据库中保存的数据是否正确。如果您无法将其作为图像打开,则保存的数据有问题:

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

答案 1 :(得分:0)

您的第一个代码段不起作用。有一个错误,因为此代码创建了一个范围块:

Using mStream As New MemoryStream()
    img.Save(mStream, img.RawFormat)
    Dim bArr As Byte() = mStream.ToArray()
End Using

关闭该块后,bArr数组超出范围(注意:未处理。刚好超出范围)以后再使用它时:

 params.Add(New SqlParameter("@Image", bArr))

要修复它,要么扩展范围块,要么在范围块之前声明bArr

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

到目前为止,这对您有用是一个意外,没有在错误的时间进行垃圾收集。我不知道这会解决您的问题,但您仍应该解决它。

要从问题中更彻底地测试问题,我会暂时更改方法,以便在上传到数据库时保留字节,以便在从数据库中检索数据时将字节与字节进行比较。查找并分析任何差异。如果它们是相同的(这是你希望的那样),那么现在是时候进入下一步了。

但是,如果我不得不猜测,当你将它保存到内存流时,我会说问题是使用img.RawFormat,这不是你期望的那种格式。在任何情况下,您都可以通过直接从文件加载字节数组来解决整个问题:

If result = Windows.Forms.DialogResult.OK Then
    Dim bArr As Byte() = IO.File.ReadAllBytes(OpenFileDialog1.FileName)
    Dim params As New List(Of SqlParameter)
    params.Add(New SqlParameter("@Image", bArr))
    CallSP("UpdateImageSP", params)
End If

最后,返回代码再次出现了范围问题,您的x Image变量可能会在它超出范围和分配给PictureBox之间的那么短的两行空间中收集:< / p>

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)
            PictureBox1.BackgroundImage = Image.FromStream(mStream) 
        End Using
    End If
End If