I'm trying to extract the images from an MS Access database and saving them into a folder but am getting that error when saving the images.
I've checked other posts all around and issue usually is not using a memory stream or closing it before doing the saving or needing to create a new instance of the image because of it being used elsewhere. My issue has all that covered and still giving the error and the weirdest thing is that it works up to some point. The first 5 images are saved onto the folder but the 6th gives that error and if I jump the 6th the 7th is saved but the 8th gives that error again.
cmdIn.Connection = con;
cmdIn.CommandText = "SELECT [ID], [FOTO], [Designação Equipamento], [MARCA], [MODELO] FROM [Fotografias e Manuais de Equipamentos]";
OleDbDataReader rdr = cmdIn.ExecuteReader();
while (rdr.Read())
{
int id = Convert.ToInt32(rdr["ID"]);
string nome="";
if (rdr["Designação Equipamento"].ToString().Equals(""))
{
nome = "semNome";
}
else
{
nome = rdr["Designação Equipamento"].ToString();
}
string nomeImagem = id + "_" + rdr["MARCA"].ToString() + "_" + rdr["MODELO"].ToString() + "_" + nome;
lblStatus.Text = string.Format("Processing ID {0}...", id);
lblStatus.Refresh();
byte[] b = (byte[])rdr["FOTO"];
byte[] imageBytes = OleImageUnwrap.GetImageBytesFromOLEField(b, 1000000);
using (MemoryStream msIn = new MemoryStream((byte[])rdr["FOTO"]))
{
Image img = Image.FromStream(msIn);
// The error pops up here in the save
img.Save(saveImagePath + nomeImagem + ".png", System.Drawing.Imaging.ImageFormat.Png);
//img.Dispose();
}
}
I've tried with and without disposing the image, it makes no difference for the error. If you want a sample of the said database here it is.
And here's the method GetImageBytesFromOLEField():
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[]>();
// 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 });
// 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 = 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;
}
Note: This issue hasn't been solved yet.