如何在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")
- BMP:
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; }注意事项:
- 若你的图片是其他格式,需添加对应格式的起始标记查找逻辑。
- 读取Oracle大BLOB时,也可使用
OracleDataReader.GetBytes方法分块读取,避免内存溢出。 - 若上述方法无效,可将下载的BLOB字节文件用十六进制编辑器打开,手动定位图片起始标记,验证查找逻辑是否正确。
内容的提问来源于stack exchange,提问作者Pedro Afonso
相关产品推荐
相关产品推荐

