在 Visual Studio C# 中从 MS Access 数据库中获取 OLE(位图)对象,我的代码有啥问题?

Posted

技术标签:

【中文标题】在 Visual Studio C# 中从 MS Access 数据库中获取 OLE(位图)对象,我的代码有啥问题?【英文标题】:Taking OLE (bitmap) object form MS Access database in Visual studio C# , What's wrong in my code?在 Visual Studio C# 中从 MS Access 数据库中获取 OLE(位图)对象,我的代码有什么问题? 【发布时间】:2017-01-31 15:29:04 【问题描述】:

我正在尝试从 MS Access DB 中获取图像。数据已正确获取,但是当我尝试显示时出现了一些错误。 我显示图像的代码是,

            ...
            byte[] photoBytes = (byte[])res[11];
            var ms = new System.IO.MemoryStream(photoBytes);
            image.Image = new System.Drawing.Bitmap(ms);
            ...

错误:附加信息:参数无效。

谁能告诉我错误在哪里,或者错误的可能性?

我的功能是

public OleDbDataReader studentInfo(String adm_no)
    
        OleDbConnection con = new OleDbConnection(ConnStr);
        con.Open();
        OleDbCommand command = new OleDbCommand("SELECT * FROM student_info WHERE adm_no = '"+adm_no+"'", con);
        OleDbDataReader res = command.ExecuteReader();
        return res;
    

【问题讨论】:

请不要发布代码截图,尤其是当它们低分辨率不可读该字段是 Ole 对象还是附件?您可以在某处发布示例数据库吗?另外,你看到了吗:***.com/questions/25864092/… 【参考方案1】:

据我所知,OLE 是野兽。如果您确定数据类型是什么,那么您有机会检查它的二进制结构。 OLE 是一个容器,因此它不仅仅是 IMO 的纯内容。

我没有代码了,但我记得在不同类型(Excel、Word、文本文件、图像...)的 OLE 的 hexdumps 中钓鱼,并最终获得了大约 80% 的成功率。如果那是因为我们决定支持的类​​型,或者我对 OLE 的内部结构的了解非常有限,我就说不出来了。

我的调试建议是在处理二进制数据之前绝对确保您拥有原始位图数据:

我的方法是创建一个小对象(在本例中为位图),将其存储在数据库中,获取它的 BLOB 并在其中查找已知模式。我记得我通过逆向工程找到了一些结构 - 例如搜索对象的字节大小 - 并且在数据开始处有一个稍微稳定的偏移量。

但是,如果您碰巧知道 - 甚至更好 - 拥有 OLE 对象的确切结构和实现并且能够处理它,我绝对相信您会管理也可以将其存储并以位图的形式打开。

祝你好运!

【讨论】:

【参考方案2】:

查看here 的示例,了解您正在尝试执行的操作,尽管该示例针对的是 JPEG 而不是位图。由于您有byte[],因此您需要执行以下操作才能进行转换:

using (MemoryStream ms = new MemoryStream(photoBytes))

  Bitmap img = (Bitmap)Image.FromStream(ms);

【讨论】:

你的意思是这样的 byte[] photoBytes = (byte[])res[11];使用 (MemoryStream ms = new MemoryStream(photoBytes)) Bitmap img = (Bitmap)Image.FromStream(ms); image.Image = new System.Drawing.Bitmap(ms); 试一试,看看效果如何。如果没有,您可能只需执行image.Image = img 就可以逃脱惩罚,因为您已经有一个 Bitmap 对象。 我认为是“MemoryStream(photoBytes)”代码的问题。正如我在编译中看到的那样,bcoz image.Image=img 也显示错误。错误显示直到我评论 MemoryStream(photoBytes) 句子 这听起来像是byte[] 变量的问题。无论出于何种原因,从photoBytes 获取MemoryStream 对象都会出现问题。【参考方案3】:

您的字节流有问题。通常我会说在将MemoryStream.Position 传递给Bitmap 构造函数之前检查它是否设置为0 - 如果它位于流的末尾,那么您可能实际上是在传递一个空的流 - 但这里不应该是这种情况。

构造函数中有几个地方会抛出参数异常,但InvaildParameter 应该与您正在检索的字节流有问题有关。见这里:https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Bitmap.cs,cbbb65af7f6fafdb,references

在这里:https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/Gdiplus.cs,4edcade52d698713

您应该验证您的字节流是否适合 GDI+ 能够作为图像加载的格式 - 例如,尝试将字节写入文件并在 Paint 中打开它。

【讨论】:

以上是关于在 Visual Studio C# 中从 MS Access 数据库中获取 OLE(位图)对象,我的代码有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 2010 Express 中从 dll 自动生成 C# 包装类?

如何在 Visual Studio 中从数据库中获取数据(使用 C#)时使 HTML 行可点击

在 Visual Studio Code 中从 NPM 包自动导入

在 Visual Studio 2013 中使用 MS Access (C#) 生成发票

MS Visual Studio 2012 Express 是不是同时包含 C#、Visual Basic、C++? [关闭]

如何在 VIsual Studio 2013 中从 UML 图生成 C++ 代码