我需要从数据库中获取图像,所以我为它编写了一些代码。问题是在某些图像中出现该错误,而在其他图像中出现无效参数错误。
OleDbConnection l = new OleDbConnection(builder.ConnectionString);
List<Image> listaImagens = new List<Image>();
List<String> listaNomes = new List<string>();
string nome = "";
try
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Fotografias e Manuais de Equipamentos] WHERE ID >26 AND ID < 30", l);
DataSet ds = new DataSet();
adapter.Fill(ds, "Fotografias e Manuais de Equipamentos");
//string s = ds.Tables["APP_Equip_Ult_Prox_Calibracao"].Columns[16].ColumnName;
foreach (DataRow row in ds.Tables["Fotografias e Manuais de Equipamentos"].Rows)
{
if (row["Designação Equipamento"].ToString().Equals(""))
{
nome = "semNome";
}
else
{
nome = row["Designação Equipamento"].ToString();
}
listaNomes.Add(row["ID"].ToString()+"_"+row["MARCA"].ToString() + "_" + row["MODELO"].ToString() + "_" + nome);
try
{
byte[] b = (byte[])row["FOTO"];
byte[] imagebyte = OleImageUnwrap.GetImageBytesFromOLEField(b, 30000);
MemoryStream ms = new MemoryStream();
ms.Write(imagebyte, 0, imagebyte.Length);
listaImagens.Add(Image.FromStream(ms));
}
catch (Exception)
{
try
{
byte[] b = (byte[])row["FOTO"];
byte[] imagebyte = OleImageUnwrap.GetImageBytesFromOLEField(b, 100000);
MemoryStream ms = new MemoryStream();
ms.Write(imagebyte, 0, imagebyte.Length);
listaImagens.Add(Image.FromStream(ms));
}
catch (Exception)
{
byte[] b = (byte[])row["FOTO"];
byte[] imagebyte = OleImageUnwrap.GetImageBytesFromOLEField(b, 600000);
MemoryStream ms = new MemoryStream();
ms.Write(imagebyte, 0, imagebyte.Length);
Image img = Image.FromStream(ms); // INVALID PARAMETER ERROR CAUGHT HERE IN DEBBUG
listaImagens.Add(img);
}
}
}
for (int i = 0; i < listaImagens.Count; i++)
{
listaImagens[i].Save("C:\\Users\\sies4578\\Desktop\\Testes\\Fotos\\" + listaNomes[i] +".png", System.Drawing.Imaging.ImageFormat.Png); //EXTERNAL EXCEPTON IN GDI+ ERROR CAUGHT HERE IN DEBBUG
}
}
catch (Exception ex)
{
MessageBox.Show("Deu o berro: "+ex.Message);
}
}
OleImageUnwrap.GetImageBytesFromOLEField用于从作为数据库中图像的 OLE 对象中删除标头,并仅获取图像本身的字节:
public static byte[] GetImageBytesFromOLEField(byte[] oleFieldBytes, int NumMaximoBytesSearch)
{
//ref http://stackoverflow.com/questions/19688641/convert-ole-object-in-datarow-into-byte-c-sharp
// 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
int MaxNumberOfBytesToSearch = NumMaximoBytesSearch;
byte[] imageBytes; // return value
var ImageSignatures = new List<byte[]>();
// BITMAP_ID_BLOCK = "BM"
ImageSignatures.Add(new byte[] { 0x42, 0x4D });
// JPG_ID_BLOCK = "\u00FF\u00D8\u00FF"
ImageSignatures.Add(new byte[] { 0xFF, 0xD8, 0xFF });
// PNG_ID_BLOCK = "\u0089PNG\r\n\u001a\n"
ImageSignatures.Add(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A });
// GIF_ID_BLOCK = "GIF8"
ImageSignatures.Add(new byte[] { 0x47, 0x49, 0x46, 0x38 });
// TIFF_ID_BLOCK = "II*\u0000"
ImageSignatures.Add(new byte[] { 0x49, 0x49, 0x2A, 0x00 });
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 = IndexOfSequence(startingBytes, 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;
}
}
那么为什么会出现这些错误呢?使用内存流生成图像时,我在保存部分的第 18 和第 26 图像处得到第一个错误,而在第 25 个图像处得到另一个错误。