views:

1321

answers:

6

I have been trying to read a picture saved in Access DB as a OLE object in a PictureBox in a C# windows Application.

The code that does this is presented below:

        string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Rajesh\SampleDB_2003.mdb;";
        OleDbConnection oConn = new OleDbConnection(connString);
        oConn.Open();
        string commandString = "select * from employee where id = " + id + "";
        OleDbCommand oCmd = new OleDbCommand(commandString, oConn);
        OleDbDataReader oReader = oCmd.ExecuteReader(CommandBehavior.SequentialAccess);

        while (oReader.Read())
        {
            txtID.Text = ((int)oReader.GetValue(0)).ToString();
            txtName.Text = (string)oReader.GetValue(1);
            txtAge.Text = ((int)oReader.GetValue(2)).ToString();
            txtType.Text = (string)oReader.GetValue(3);
            byte[] imageBytes = (byte[])oReader.GetValue(4);

            MemoryStream ms = new MemoryStream();
            ms.Write(imageBytes, 0, imageBytes.Length);
            Bitmap bmp = new Bitmap(ms);
            pbPassport.Image = bmp;
        }

When I execute the above code, an 'Parameter is not valid' exception is thrown at the line:

Bitmap bmp = new Bitmap(ms)

From the exception message, it is clear that 'ms' is in a format that is not recognisable. Any suggestion to get past this?

A: 

Unfortunately I have no good answer for you, but I can tell you that when I tried, I got the same results. Sometimes skipping the first 78 bytes of the byte array worked, sometimes it didn't.

This is because the OLE Object datatype stores some kind of header in the field, so that Access knows what type of OLE Object it is. I could not find a reliable way to work out exactly where this header stopped and real data started, but I also gave up, so good luck :)

Ch00k
A: 

Your bytestream is corrupted somehow, becouse I tried the exact method of yours but filled the byte array with PNG data from a file instead.

I would suggest creating two streams, one from the database, and one from the file that was the source of the image in the database. Then compare them byte by byte. If there is even one byte of diffrence, the database image data is corrupt.

CooPs
A: 

You can try:

pbPassport.Image = Image.FromStream(ms);
milot
+1  A: 

Do a google search for AccessHdr. You'll find references to AccessHdr.cpp and AccessHdr.h. These will illustrate what is need to extract the streams without the header.

Joel Lucsy
+1  A: 

and????? What happend? I got the same prob!

Regards David

A: 

You can't read OLE objects so easily. In fact, it is bad practice to keep pictures as OLE objects in database.

It is preferred to have em as BLOB objects or path and filename at some storage. AccessImagine can handle both scenarios for MS Access and C#. You can download it here - http://access.bukrek.net