You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中读取Oracle中源自Access的OLE格式BLOB图片?

解决C#读取Oracle中Access OLE图片BLOB的问题
  • 问题根源:通过Ctrl+V粘贴到Access表单的图片是以OLE对象格式存储的,Oracle中的BLOB包含OLE容器的结构头,并非纯原始图片字节流,直接用Image.FromStream读取会因格式不合法报错。

  • 解决方案:解析OLE字节数组,定位到原始图片数据的起始位置,截取有效字节后再转换为Image。常见图片格式的起始标记:

    • BMP:0x424D(对应ASCII的"BM")
    • JPG/JPEG:0xFFD8
    • PNG:0x89504E47(对应ASCII的"‰PNG")
  • C#代码示例:

    using System;
    using System.Data.OracleClient;
    using System.Drawing;
    using System.IO;
    
    public Image GetImageFromOracleOleBlob(string connectionString, string query)
    {
        using (OracleConnection conn = new OracleConnection(connectionString))
        {
            conn.Open();
            using (OracleCommand cmd = new OracleCommand(query, conn))
            {
                byte[] oleBlob = (byte[])cmd.ExecuteScalar();
                if (oleBlob == null || oleBlob.Length == 0)
                    return null;
    
                // 优先查找JPG起始标记,可根据实际图片类型调整顺序
                int startIndex = FindImageStart(oleBlob, new byte[] { 0xFF, 0xD8 });
                if (startIndex == -1)
                {
                    // 尝试查找BMP标记
                    startIndex = FindImageStart(oleBlob, new byte[] { 0x42, 0x4D });
                }
                if (startIndex == -1)
                {
                    // 尝试查找PNG标记
                    startIndex = FindImageStart(oleBlob, new byte[] { 0x89, 0x50, 0x4E, 0x47 });
                }
    
                if (startIndex == -1)
                    throw new Exception("未找到有效图片起始标记");
    
                // 截取有效图片字节段
                byte[] imageBytes = new byte[oleBlob.Length - startIndex];
                Array.Copy(oleBlob, startIndex, imageBytes, 0, imageBytes.Length);
    
                using (MemoryStream ms = new MemoryStream(imageBytes))
                {
                    return Image.FromStream(ms);
                }
            }
        }
    }
    
    // 辅助方法:在字节数组中查找指定标记的起始位置
    private int FindImageStart(byte[] source, byte[] marker)
    {
        for (int i = 0; i <= source.Length - marker.Length; i++)
        {
            bool match = true;
            for (int j = 0; j < marker.Length; j++)
            {
                if (source[i + j] != marker[j])
                {
                    match = false;
                    break;
                }
            }
            if (match)
                return i;
        }
        return -1;
    }
    
  • 注意事项:

    1. 若你的图片是其他格式,需添加对应格式的起始标记查找逻辑。
    2. 读取Oracle大BLOB时,也可使用OracleDataReader.GetBytes方法分块读取,避免内存溢出。
    3. 若上述方法无效,可将下载的BLOB字节文件用十六进制编辑器打开,手动定位图片起始标记,验证查找逻辑是否正确。

内容的提问来源于stack exchange,提问作者Pedro Afonso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:10:05