2010-01-26 35 views
6

我有简单的数据库在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); 
} 
+0

当您查看包含图像列的MS Access表时,您在该字段中看到了哪些文本?它是'长二进制数据'还是不同的? – Stewbob 2010-02-11 19:19:05

回答

6

如果直接从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对象,然后创建从流中图像对象。这段代码工作得很好,并将图像显示在我的表单上的一个图片框中。

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数组您的具体情况的前部和后部。

我决定为我的文件通过比较原始图像文件,并从数据库中导出的文件,(不流对象,见我的第一个代码)在十六进制编辑器。一旦我计算出MS Access添加了多少信息(页眉和页脚),我就知道需要剥离多少个字节。

编辑:

由MS访问添加时的图像被存储为“包”的变化取决于文件类型,图像时的原始位置(完整路径信息)的报头的大小它被转储到MS Access数据库中。因此,即使是相同的文件类型,您也可以从每个文件的标题中除去不同数量的字节。 这使得它变得更加困难,因为那样你将不得不扫描字节数组,直到找到该文件类型的正常文件开始信息,然后剥去它之前的所有内容。

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

+0

但是,当我试图实例化Image类型的对象时,传递字节数组(varBytes在你的例子中)作为构造函数参数,我得到错误:参数无效。当然,这是一个有效的字节数组(长度大约3000字节 - 取决于图像大小)。 – Dariusz 2010-02-11 18:45:58

+0

感谢看来,没有一种解决方案可以获得OleObject头的长度。感谢您的支持。 – Dariusz 2010-02-15 11:01:15

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); 
    } 
+0

注意:这是假设您从数据库调用中取回有效值。 – Aaron 2010-02-11 20:07:30