从数据库检索图像时,似乎无法真正解决我真正的问题Invalid参数,所以Imma一步一步尝试。在C#和MS Access 2010中使用Visual Studio2012。我的解决方案是与网络无关的应用程序。
我不知道这部分所以在这里我的问题是关于如何正确得到的图像 OLE对象 是在 一行 从查询到一个字节数组( 字节[] ),因为它肯定不是我怎么正在使用以下代码进行操作。我要说的行是 row [“ FOTO”] 。
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [APP_Equipamento_Geral] WHERE COD_ETIQ like '%" + codigo + "%'", l); DataSet ds = new DataSet(); adapter.Fill(ds, "[APP_Equipamento_Geral]"); string s = ds.Tables["[APP_Equipamento_Geral]"].Columns[16].ColumnName; foreach (DataRow row in ds.Tables["[APP_Equipamento_Geral]"].Rows) { eq.NSerie = row["N_SERIE"].ToString(); eq.NInventario = row["Codigo"].ToString(); if (row["FOTO"] != DBNull.Value && row["FOTO"] != null) { string str = row["FOTO"].ToString(); byte[] b = stringToByteArray(str); byte[] imagebyte = GetImageBytesFromOLEField(b); //Error caught here MemoryStream ms = new MemoryStream(); ms.Write(imagebyte, 0, imagebyte.Length); } }
方法GetImageBytesFromOLEField可以在这里找到。它给我的错误是关于行 字符串 处的索引长度 strVTemp = strTemp.Substring(0,300);
同样,这里的主要问题是如何将 DataRow行[“ FOTO”]中 的 OLE对象 转换为 byte [] ,然后在该方法中使用。
这里的问题是,嵌入的图像不是简单的BMP或JPEG。那是个
BMP
JPEG
Microsoft Word Picture
并且OLE标头信息比原始GetImageBytesFromOLEField()代码的300字节窗口大得多。(也就是说,在扫描300个字节后,它只是放弃了“无法确定标头大小…”。)
GetImageBytesFromOLEField()
以下是该代码在其自己的类中的更新版本。课程测试包括提供的Microsoft Word Picture,简单的BMP和简单的JPEG。
using System; using System.Collections.Generic; using System.Linq; namespace OleImageTest { public static class OleImageUnwrap { public static byte[] GetImageBytesFromOLEField(byte[] oleFieldBytes) { // adapted from http://blogs.msdn.com/b/pranab/archive/2008/07/15/removing-ole-header-from-images-stored-in-ms-access-db-as-ole-object.aspx const int maxNumberOfBytesToSearch = 10000; byte[] imageBytes; // return value var imageSignatures = new List<byte[]>(); // PNG_ID_BLOCK = "\x89PNG\r\n\x1a\n" imageSignatures.Add(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }); // JPG_ID_BLOCK = "\xFF\xD8\xFF" imageSignatures.Add(new byte[] { 0xFF, 0xD8, 0xFF }); // GIF_ID_BLOCK = "GIF8" imageSignatures.Add(new byte[] { 0x47, 0x49, 0x46, 0x38 }); // TIFF_ID_BLOCK = "II*\x00" imageSignatures.Add(new byte[] { 0x49, 0x49, 0x2A, 0x00 }); // BITMAP_ID_BLOCK = "BM" imageSignatures.Add(new byte[] { 0x42, 0x4D }); int numberOfBytesToSearch = (oleFieldBytes.Count() < maxNumberOfBytesToSearch ? oleFieldBytes.Count() : maxNumberOfBytesToSearch); var startingBytes = new byte[numberOfBytesToSearch]; Array.Copy(oleFieldBytes, startingBytes, numberOfBytesToSearch); var positions = new List<int>(); foreach (byte[] blockSignature in imageSignatures) { positions = startingBytes.IndexOfSequence(blockSignature, 0); if (positions.Count > 0) { break; } } int iPos = -1; if (positions.Count > 0) { iPos = positions[0]; } if (iPos == -1) throw new Exception("Unable to determine header size for the OLE Object"); imageBytes = new byte[oleFieldBytes.LongLength - iPos]; System.IO.MemoryStream ms = new System.IO.MemoryStream(); ms.Write(oleFieldBytes, iPos, oleFieldBytes.Length - iPos); imageBytes = ms.ToArray(); ms.Close(); ms.Dispose(); return imageBytes; } private static List<int> IndexOfSequence(this byte[] buffer, byte[] pattern, int startIndex) { // ref: http://stackoverflow.com/a/332667/2144390 List<int> positions = new List<int>(); int i = Array.IndexOf<byte>(buffer, pattern[0], startIndex); while (i >= 0 && i <= buffer.Length - pattern.Length) { byte[] segment = new byte[pattern.Length]; Buffer.BlockCopy(buffer, i, segment, 0, pattern.Length); if (segment.SequenceEqual<byte>(pattern)) positions.Add(i); i = Array.IndexOf<byte>(buffer, pattern[0], i + 1); } return positions; } } }