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

Taking OLE (bitmap) object form MS Access database in Visual studio C# , What's wrong in my code?

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

            ...
            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;
    }

查看 here 示例,了解您正在尝试执行的操作,尽管该示例适用于 JPEG 而不是位图。因为你有一个 byte[],你需要做这样的事情来转换:

using (MemoryStream ms = new MemoryStream(photoBytes))
{
  Bitmap img = (Bitmap)Image.FromStream(ms);
}

你的字节流有问题。通常我会说在将 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 中打开它。

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

我没有代码了,但我记得在不同类型(Excel、Word、文本文件、图像等)的 OLE 的 hexdump 中钓鱼并以成功率告终可能占 80%。如果那是因为我们决定支持的类​​型,或者我对 OLE 内部结构的了解非常有限,我就不知道了。

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

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

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

祝你好运!