0

I have a table that has a photo column in it, one of the users decided to start saving 20MB images into the field, which consequently caused the database to jump up in size by a factor of 6 in less than a year. So my ultimate goal is to iterate through the table, pull the image, resize and crop it, then save it back to the database.

So my initial thought was this data is being saved as a blob byte array so i'm trying:

public static Bitmap ByteToImage(byte[] blob)
{
    using (var mStream = new MemoryStream())
    {
        mStream.Write(blob, 0, blob.Length);
        mStream.Seek(0, SeekOrigin.Begin);
        var bm = new Bitmap(mStream);
        return bm;
    }
}

//Method
const string myConnectionString = @"Driver={Microsoft Access Driver (*.mdb)};  Dbq=E:\SUFDB2006NoPics.mdb;Uid=Admin;Pwd=;";

using(var myConnection = new OdbcConnection())
{
    myConnection.ConnectionString = myConnectionString;
    myConnection.Open();
    var dadapter = new OdbcDataAdapter("Select [Contact ID#], [Photo] FROM Contact", myConnection);
    var table = new DataTable();
    dadapter.Fill(table);

    foreach (DataRow row in table.Rows)
    {
       var pht = (byte[])row["Photo"];

       //Tried this 1
       var stream = new MemoryStream(pht); //Parameter is not valid Error.
       pictureBox1.Image = Image.FromStream(stream);

       //Tried this 2
       pictureBox1.Image = ByteToImage(pht);

    }

    this.dataGridView1.DataSource = table; //However this works no problem
    dataGridView1.Refresh();
}

So, interestingly the image column binds to a datagridview no problem. However when I try to bind an individual image row to a picturebox it throws an error. I would put the binary up but its WAY to long. The images are not corrupt as they pull up no problem in the datagridview.

Am i going about this the right way ? Is the data stored as a blob the same way it is in a SQL Server Database ? Also if anyone know of an easier way to do this that would be great. Thanks

Edit

Binary Data in Text File. Too Big to put here is a Link

...and a screenshot:

OleWrapped.png

Gord Thompson
  • 116,920
  • 32
  • 215
  • 418
bumble_bee_tuna
  • 3,533
  • 7
  • 43
  • 83

1 Answers1

3

I've had a look at the file you posted, and it looks you're storing your image as an OLE object rather than the bytes of an image. The OLE container prepends a header to your file, which is why you can't decode the byte array directly into an image.

In the case of the file you provided, the bitmap image starts at byte 79 with the BMP header 424D.

This answer has some links that should help you out.

Community
  • 1
  • 1
GavinH
  • 2,173
  • 1
  • 15
  • 17
  • 1
    There is also a related answer of mine [here](http://stackoverflow.com/a/19709053/2144390) from a few months back. It includes a C# class to remove the OLE header information from the bytes that are retrieved from the Access database. – Gord Thompson Feb 02 '14 at 10:11
  • 1
    Nice one Gord! @bumble_bee_tuna Be aware that if you resize an image and save it back to the database, you'll be saving image bytes only and not an OLE object. If you're not careful, you'll end up with a mix of raw and OLE images in your database. – GavinH Feb 02 '14 at 11:57
  • 1
    @bumble_bee_tuna Gavin raises an excellent point. If you want to save the images back as OLE objects there is a recent question [here](http://stackoverflow.com/q/21497937/2144390) that provides a solution, of sorts. – Gord Thompson Feb 02 '14 at 12:20
  • @GordThompson Is the Ole header static or variable ? – bumble_bee_tuna Feb 02 '14 at 21:52
  • 1
    @bumble_bee_tuna In my experience it has proven to be variable. VERY variable. – Gord Thompson Feb 02 '14 at 23:24