从Access读取图像 - 参数无效

时间:2010-01-26 15:17:55

标签: c# ms-access oledb

我在Access .mdb文件中有简单的数据库,但是当我从流中创建Image时,我不知道如何处理:“参数无效”异常。 我读过我需要删除78个字节的偏移量(from here),但我仍然得到“参数无效”错误 当我调用FromStream时,即使剥离了前78个字节。


这对我不起作用:

byte[] abytPic = (byte[])dt.Rows[0]["Photo"]; byte arrary with image
if ((abytPic[0] == 21) && (abytPic[1] == 28)) //It's true
{
    byte[] abytStripped = new byte[abytPic.Length - 78];
    System.Buffer.BlockCopy(abytPic, 78, abytStripped, 0, abytPic.Length - 78); 
    msPic = new emoryStream(abytStripped);
}

2 个答案:

答案 0 :(得分:7)

如果直接从MS Access读取数据,则无需删除任何标头信息。

假设图像存储为BLOB,这是最常见的,这里是从数据库中读取字节数组并作为图像文件存储的代码(抱歉,VB而不是C#):

  Dim varBytes() As Byte

  Using cn As New OleDbConnection(myConnectionString)
     cn.Open()

     sqlText = "SELECT [myColumn] " _
              & "FROM [myTable] " _
              & "WHERE ([mySearchCriteria] = '" & mySearchTerm & "')"

     Using cm As New OleDbCommand(sqlText, cn)
        Dim rdr As OleDbDataReader

        rdr = cm.ExecuteReader

        rdr.Read()

        varBytes = rdr.GetValue(0)
     End Using

  End Using

  My.Computer.FileSystem.WriteAllBytes(myPath & "\myFile.emf", varBytes, True)

我放置的这个例子是我知道数据库中的文件是.emf图像的例子。如果您知道扩展名,可以将其放在文件名上。如果不这样做,可以将其留空,然后使用图像查看器打开结果;它应该开始。如果您需要查找扩展名或文件类型,一旦将其保存为文件,您可以使用任何十六进制编辑器打开它,并且标题信息中将提供文件类型。

您的问题有点不清楚,所以我不确定上面的代码是否符合您的要求,但它应该让您更接近。

修改

这是VB代码,它接受字节数组,将其加载到MemoryStream对象中,然后从Stream创建一个Image对象。这段代码运行得很好,并在我的表单上的图片框中显示图像。

  Dim img As Image
  Dim str As New MemoryStream(varBytes)
  img = Image.FromStream(str)
  PictureBox1.Image = img

如果相应的C#不适合您,则问题可能出在图像存储在MS Access数据库中的方式。

修改

如果数据库中的图像存储为“包”而不是“长二进制数据”,则需要删除MS Access添加的标题信息。我一直在使用简单的.jpg文件播放'Package'类型的图像存储。在这种情况下,标头远远超过78个字节。在这个例子中,它实际上是234个字节,MS Access也在原始文件的末尾添加了一些信息;在这种情况下大约292个字节。

看起来你的原始方法是正确的,你只需要确定在你的情况下剥离Byte数组前后的字节数。

我通过在十六进制编辑器中比较原始图像文件和从数据库导出的文件(而不是Stream对象,请参阅我的第一个代码)来确定我的文件。一旦我弄清楚MS Access添加了多少信息(页眉和页脚),我就知道需要剥离多少字节。

修改

当图像存储为“打包”时,MS Access添加的标题大小取决于文件类型以及图像转储到MS Access数据库时的原始位置(完整路径信息)。因此,即使对于相同的文件类型,您也可能从每个文件的标题中剥离不同的字节数。 这使得它变得更加困难,因为那时你必须扫描字节数组,直到找到该文件类型的正常文件启动信息,然后在它之前删除所有内容。

所有这些令人头疼的原因之一就是将图像作为BLOBs的“长二进制数据”存储在数据库中更好。检索更容易。我不知道你是否可以选择这样做,但如果是这样,那将是一个好主意。

答案 1 :(得分:1)

我不相信你的问题与数据库有关。处理成像时“参数无效”异常可能是一种彻底的痛苦,因为我之前已经处理过它们。他们不清楚问题是什么。

图像到底是如何放入数据库的?在您尝试拉动图像之前将图像写入数据库可能会出现问题。另外,图像的文件类型是什么?

编辑以下是我之前使用的一些示例代码,用于从字节数组中获取图像。

        //takes an array of bytes and converts them to an image.
    private Image getImageFromBytes(byte[] myByteArray)
    {            
        System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length);
        return Image.FromStream(newImageStream, true);
    }