How to extract an OLE Object (Bitmap Image) from JET?

  • Thread starter Thread starter deko
  • Start date Start date
D

deko

I have a Windows Forms app that connects to an Access database. One of the
tables in the database contains a bunch of pictures stored in OLE Object
fields.

What I need to do is extract those pictures to the file system so the user
can do stuff with the image. For example, the user would select the name of
the image from a combo box and then somePicture.bmp would be extracted from
the Access database to the temp directory.

Is there an easy way to do this? Examples? Other suggestions?

Thanks in advance.
 
The OLE Object header added by Access has never been documented by MS;
however, its observed length seems to be 78 bytes in all cases that I seen
so far; so, all you have to do is to strip the first 78 bytes and kept the
remaining.
 
The OLE Object header added by Access has never been documented by MS;
however, its observed length seems to be 78 bytes in all cases that I seen
so far; so, all you have to do is to strip the first 78 bytes and kept the
remaining.

Sounds good. Thanks for the tip. But I really have no idea how to do
that... could you provide an example?
 
I found the below code at http://sastools.com/b2/post/79394244

But I'm not sure what the class definition for MemoryStream is. My guess is
it's something well-known since the author left it out - still, I have no
idea with it is.

private void Page_Load(object sender,
System.EventArgs e)
{
SqlConnection cn;
cn = new SqlConnection
("DATABASE=northwind;SERVER=localhost;UID=sa;");
String cmdText = "SELECT photo FROM Employees WHERE employeeid=" +
Request["id"].ToString();
SqlCommand cmd = new SqlCommand(cmdText, cn);

MemoryStream ms = new MemoryStream();

// 78 is the size of the OLE header for Northwind images.
// There's no header in PUBS as PUBS
// just contains the raw image bits.
int offset = 78;

cn.Open();
byte [] img = (byte[]) cmd.ExecuteScalar();
ms.Write(img, offset, img.Length-offset);
cn.Close();

Bitmap bmp = null;
bmp = new Bitmap(ms);
Response.ContentType = "image/gif";
bmp.Save(Response.OutputStream, ImageFormat.Gif);
ms.Close();
}
 
Hi,

I cannot help you anymore on this topic because I never had to perform
this operation in the .NET platform.

For your example, MemoryStream is a standard .NET class; see
http://msdn.microsoft.com/library/d.../html/frlrfsystemiomemorystreamclasstopic.asp .

You will also find many exemple on the internet where the images are
extracted from the database in chunks (blocks) instead of being retrieved in
a single step. See
http://support.microsoft.com/default.aspx?scid=kb;EN-US;317034 for example.
It should be very easy to adapt this procedure to first read a chunk of 78
bytes and then drop it.
 
For your example, MemoryStream is a standard .NET class; see
http://msdn.microsoft.com/library/d.../html/frlrfsystemiomemorystreamclasstopic.asp .

You will also find many exemple on the internet where the images are
extracted from the database in chunks (blocks) instead of being retrieved
in a single step. See
http://support.microsoft.com/default.aspx?scid=kb;EN-US;317034 for
example. It should be very easy to adapt this procedure to first read a
chunk of 78 bytes and then drop it.

Thanks - that helps. I'm kind of a newbie, but I've got this far:

class GetImage
{
private System.Data.OleDb.OleDbConnection oleDbCnx;
private System.Data.OleDb.OleDbCommand oleDbCmd;

public GetImage(string artName)
{
oleDbCnx = new OleDbConnection();
oleDbCnx.ConnectionString =
("Provider=Microsoft.Jet.OLEDB.4.0; Data Source="
+ Application.StartupPath + @"\DrinkMateImages.mdb");
string strSql = "SELECT Photo FROM Photos WHERE ArtworkName = "
+
artName;
oleDbCmd = new OleDbCommand(strSql, oleDbCnx);
}
private bool ToTempDir()
{

MemoryStream ms = new MemoryStream();
int offset = 78;
oleDbCnx.Open();
byte[] img = (byte[])oleDbCmd.ExecuteScalar();
ms.Write(img, offset, img.Length - offset);
oleDbCnx.Close();
Bitmap bmp = null;
bmp = new Bitmap(ms);
//how to get temp Dir?
bmp.Save("C:\temp", ImageFormat.Bmp);
ms.Close();
oleDbCnx.Close();
return true;
}
}
}
 
Back
Top