Removing OLE Header from images stored in MS Access DB as OLE Object

This is the first non-SharePoint blog post I am writingJ. I am writing because this is interesting and it seems lots of people faced or facing similar issues.  If you are storing images in Access DB table as OLE object, and you are adding images programmatically (for example uploading images from an aspx page), then you might not face this issue. This problem occurs when you are adding images directly into the Access database table after opening it through MS Access client. When you try to retrieve those images you will find those do not open in Web Pages or any other program. This is because Access adds OLE Header in front of those images.

Here is a function that will remove the OLE Header from different types of images. I found the original code with the example of BMP, JPEG images somewhere I forgot the source and it was also referred by Andy Spears (MS Partner). Rest is done by me.

private byte[] GetImageBytesFromOLEField(byte[] oleFieldBytes)


        const string BITMAP_ID_BLOCK = “BM”;

        const string JPG_ID_BLOCK = “\u00FF\u00D8\u00FF”;

        const string PNG_ID_BLOCK = “\u0089PNG\r\n\u001a\n”;

        const string GIF_ID_BLOCK = “GIF8”;

        const string TIFF_ID_BLOCK = “II*\u0000”;


        byte[] imageBytes;


        // Get a UTF7 Encoded string version

        Encoding u8 = Encoding.UTF7;

        string strTemp = u8.GetString(oleFieldBytes);


        // Get the first 300 characters from the string

        string strVTemp = strTemp.Substring(0, 300);


        // Search for the block

        int iPos = -1;

        if (strVTemp.IndexOf(BITMAP_ID_BLOCK) != -1)

            iPos = strVTemp.IndexOf(BITMAP_ID_BLOCK);

        else if (strVTemp.IndexOf(JPG_ID_BLOCK) != -1)

            iPos = strVTemp.IndexOf(JPG_ID_BLOCK);

        else if (strVTemp.IndexOf(PNG_ID_BLOCK) != -1)

            iPos = strVTemp.IndexOf(PNG_ID_BLOCK);

        else if (strVTemp.IndexOf(GIF_ID_BLOCK) != -1)

            iPos = strVTemp.IndexOf(GIF_ID_BLOCK);

        else if (strVTemp.IndexOf(TIFF_ID_BLOCK) != -1)

            iPos = strVTemp.IndexOf(TIFF_ID_BLOCK);


            throw new Exception(“Unable to determine header size for the OLE Object”);


        // From the position above get the new image

        if (iPos == -1)

            throw new Exception(“Unable to determine header size for the OLE Object”);



        imageBytes = new byte[oleFieldBytes.LongLength – iPos];

        MemoryStream ms = new MemoryStream();

        ms.Write(oleFieldBytes, iPos, oleFieldBytes.Length – iPos);

        imageBytes = ms.ToArray();



        return imageBytes;


Comments (7)

  1. Douglas V. Pasqua says:


    A Java version of this code:


  2. Verok says:

    Eversome. Thank you

  3. Mitchell says:


    Please could you tell me how I could use this in JAVA?



    myemail [AT] mrincworld [DOT] com

  4. KK says:

    This seems to be what I'm looking for, but how do I use it?  I need to convert 350 records that contain 1 ole picture column.

  5. Rennie Petersen says:

    Thank you very much for your article. The concept and the signature bytes for the various graphic file formats was worth gold.

    On the other hand, I can not understand how your program can work, due to your use of UTF-7 encoding before you search for the signature bytes. If the OLE header contains some high-value bytes that causes UTF-7 to produce several characters, then the resulting position will be off by 1 or 2 or 3, won’t it?

    Another problem I faced is that some Access users went and created Picture objects instead of Package objects. This results in an OLE header followed by a DIB structure, which can not be processed like the graphics files. Fortunately I found a solution on another blog – if any other readers stumble on this article here is the link:

  6. Ron says:

    Fantastic! This is pure genius! I was having a real headache trying to get jpeg data in an Access OLE object field to display in the browser until I stumbled across your code here. I reckon that without good programmers like yourself sharing information like this we’d all be a lot worse off. *two thumbs up*

Skip to main content