views:

396

answers:

2

Hello,

I'm working on redeveloping an Access based system into c#.net, however when MS went from office 2003 to office 2007 they removed the picture editor within access - which meant that previously stored pictures would no longer display in the system. The guys at the company did a hack that basically saved the images with VBA using excel in the background (I can get more information if you need it) but basically it meant the access image controls could still be used (Object bound frames).

However, I now have the problem of trying to display these in .NET applications, and after countless days of trying different ways of manipulating the byte array I'm close to giving up. I have tried at least 8 different suggested solutions and each one ends with a 'Parameter not recognised' exception when doing Image.fromStream(). Below is the code which has got me the closest so far:

    private void imageExtractTest()
    {
        LogOnDataSetTableAdapters.QueriesTableAdapter qa =
            new SchoolBaseLogon.LogOnDataSetTableAdapters.QueriesTableAdapter();

        object docO = qa.GetLogonImage();
        if (docO == null || !(docO is byte[]))
        {
            return;
        }
        byte[] doc = (byte[])docO;

        MemoryStream ms = new MemoryStream();
        ms.Write(doc, 0, doc.Length);
        int firstByte;
        int secondByte;
        ms.Seek(0, SeekOrigin.Begin);
        firstByte = ms.ReadByte();
        secondByte = ms.ReadByte();

        if (firstByte != 0x15 && secondByte != 0x1C)
        {
            //ErrorResponse("Stored object is not an Access File.");
            return;
        }

        int fileTypeLoc = 20; // begin of the file type
        short offset; // end of the file type

        byte[] buffer = new byte[2];
        ms.Read(buffer, 0, 2);
        offset = BitConverter.ToInt16(buffer, 0);

        long seekTotal = 0;
        seekTotal += offset;

        string docType = String.Empty;
        for (int i = fileTypeLoc; i < offset; i++)
        {
            docType += (char)doc[i];
        }

        //if I query docType now I get 'Picture\0\0'

        // magic eight bytes 01 05 00 00 03 00 00 00
        ms.Seek(seekTotal, SeekOrigin.Begin);
        buffer = new byte[8];
        ms.Read(buffer, 0, 8);
        seekTotal += 8;

        // Second offset to move to 
        buffer = new byte[4];
        ms.Read(buffer, 0, 4);
        seekTotal += 4;
        long offset2 = BitConverter.ToInt32(buffer, 0);
        seekTotal += offset2;
        ms.Seek(seekTotal, SeekOrigin.Begin);

        // eight empty bytes
        buffer = new byte[8];
        ms.Read(buffer, 0, 8);
        seekTotal += 8;

        // next n bytes are the length of the file
        buffer = new byte[4];
        ms.Read(buffer, 0, 4);
        seekTotal += 4;
        long fileByteLength = BitConverter.ToInt32(buffer, 0);

        // next N bytes are the file
        byte[] data = new byte[fileByteLength];

        // store file bytes in data buffer
        ms.Read(data, 0, Convert.ToInt32(fileByteLength));

        MemoryStream imageStream = new MemoryStream(data);
        Image test = Image.FromStream(imageStream);
    }

This code was adapted from here, I didn't need the various doctypes identification as I'm only dealing with images, however the image type could be any number of things - jpg, bmp, gif, png etc.

I've also tried saving the outputted byte array but I've had no luck viewing that either. But when I point access to the database and get it to view it, everything is fine. Also the .NET Crystal Report designer is able to get these images some how - so they must be in there somewhere...

Has anyone got any ideas?

Marlon

+1  A: 

Trying to retrieve an MS-access OLE image field from .NET is way more headache than it is worth. There is some good discussion and info about this topic in this post.

Ultimately, your best, and easiest, solution to be successful with this is to use your working viewing method to save these images as separate files, then import those files into the database as BLOB fields, rather than image fields. Then you can easily read them into .NET.

Stewbob
A: 

Try this KB http://support.microsoft.com/kb/317701 article from microsoft. It contains information on how to access the image blob from access and display that in winforms application.

ferosekhanj
thanks for the info but I think you misunderstand the problem. That article just explains how to store a image file into a database. Not how to convert an already stored OLE object to a image. Apparently OLE is just magic...
Marlon