none
Picture Extraction from MS Access RRS feed

  • Question

  • Hi

     

    I am currently trying to load images from an access database so that I can put them into a picturebox.  But I am currently getting the following error:

     

    An unhandled exception of type 'System.ArgumentException' occurred in system.drawing.dll

    Additional information: Invalid parameter used.

     

    On the line -

    m_oPicturePreviewArray[iRow].Image = Image.FromStream(imageByteData);

     

     

    The code I have used is listed below (it is placed in the load part of my form where I have several picture boxes loaded in a control array).  I have created a simple database one access table named Images containing two fields named KeyID (autonumber key) and image (OLE Object).  I load the images in by right clicking no the cell and clicking on the lnsert Object ... and then loading a jpeg file from my harddrive.

     

    Does anyone know what I am doing wrong or how to do what I am trying to do?

     

    Thanks

     

    // Load in the images

    string sQuery;

    System.IO.MemoryStream imageByteData;

    sQuery = "SELECT image FROM images";

    OleDbConnection oConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\Test App\\Images.mdb;Jet OLEDBBig Smileatabase Password=;");

    oConnection.Open();

    OleDbDataAdapter oAdapter = new OleDbDataAdapter(sQuery, oConnection);

    System.Data.DataTable dtTable = new System.Data.DataTable();

    dtTable.Clear();

    int iNumberOfRows = oAdapter.Fill(dtTable);

    if (iNumberOfRows > 0)

    {

    PictureArray = new ArrayList();

    int iRow = 0;

    foreach (System.Data.DataRow dtRow in dtTable.Rows)

    {

    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

     

    byte[] imageData;

    imageData = (byte[])(dtRow["image"]);

    imageByteData = new System.IO.MemoryStream();

    bf.Serialize(imageByteData, dtRow["image"]);

    m_oPicturePreviewArray[iRow].Image = Image.FromStream(imageByteData);

    iRow += 1;

    }

    }

    else

    System.Windows.Forms.MessageBox.Show("No Rows Of Data");

    Tuesday, September 18, 2007 4:15 PM

Answers

  • Well I have managed to solve the problem myself, sure there must be others around here that knew what to do but in case anyone else needs to know when extracting a JPG file from access the starting point always changes so you have to search for it.  I've got code to a simple program that searches through a database on the D drive (Images.mdb which contains one table (Images) with two fields in it (KeyID - autonumber and primary key and Image - OLE Object that holds the images).  Recreate the table, open a new C# windows application.

     

    Add the following controls to the form:

    Two Buttons, set Button 1 text to 'Open Database', set Button 2 text to 'Get Image'

    One Label

    One Textbox, clear the text property

    One picturebox, set the Sizemode property to stretchimage

     

    and then add the following code:

     

    In the Using bitty right at the top:

    using System.Data.OleDb;

    using System.IO;

    using System.Text;

     

    Global Declarations in the class:

    private OleDbConnection aConnection;

    private OleDbCommand aCommand;

     

    Button 1 Click event:

    //create the database connection

    aConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\\Images.mdb");

    aConnection.Open();

    if (aConnection.State == ConnectionState.Open)

    label1.BackColor = System.Drawing.Color.WhiteSmoke;

     

    Button 2 Click event:

    const string BITMAP_ID_BLOCK = "Bitmap";

    const string JPG_ID_BLOCK = "\u00FF\u00D8\u00FF";

    //create the command object and store the sql query

    aCommand = new OleDbCommand("select Image from Images where KeyID = " + textBox1.Text, aConnection);

    MemoryStream ms = new MemoryStream();

    // 78 is the size of the OLE header for Bitmap images.

    // JPEG images adjust the header, search for it :-)

    // Execute the command and only ever return one result (Scalar)

    byte [] img = (byte[]) aCommand.ExecuteScalar();

    // Get a UTF7 Encoded string version

    Encoding u8 = Encoding.UTF7;

    string strTemp = u8.GetString(img);

    // Get the first 300 characters from the string

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

    int iPos = -1;

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

    {

    // Find the starting block of the image

    iPos = strVTemp.IndexOf(JPG_ID_BLOCK);

    }

    else

    {

    iPos = 78;

    }

    // From the position above get the new image

    if (iPos != -1)

    {

    ms.Write(img, iPos, img.Length - iPos);

    this.pictureBox1.Image = Image.FromStream(ms);

    }

    ms.Close();

     

     

    Then all you have to do is type in the index of the image you want to view in the database (the KeyID) and bob's your uncle ....  A wee side note, there is absolutely no error checking so it will crash if you do something wrong :-)  Byeee

    Wednesday, September 19, 2007 1:14 PM

All replies

  • Well I have managed to solve the problem myself, sure there must be others around here that knew what to do but in case anyone else needs to know when extracting a JPG file from access the starting point always changes so you have to search for it.  I've got code to a simple program that searches through a database on the D drive (Images.mdb which contains one table (Images) with two fields in it (KeyID - autonumber and primary key and Image - OLE Object that holds the images).  Recreate the table, open a new C# windows application.

     

    Add the following controls to the form:

    Two Buttons, set Button 1 text to 'Open Database', set Button 2 text to 'Get Image'

    One Label

    One Textbox, clear the text property

    One picturebox, set the Sizemode property to stretchimage

     

    and then add the following code:

     

    In the Using bitty right at the top:

    using System.Data.OleDb;

    using System.IO;

    using System.Text;

     

    Global Declarations in the class:

    private OleDbConnection aConnection;

    private OleDbCommand aCommand;

     

    Button 1 Click event:

    //create the database connection

    aConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\\Images.mdb");

    aConnection.Open();

    if (aConnection.State == ConnectionState.Open)

    label1.BackColor = System.Drawing.Color.WhiteSmoke;

     

    Button 2 Click event:

    const string BITMAP_ID_BLOCK = "Bitmap";

    const string JPG_ID_BLOCK = "\u00FF\u00D8\u00FF";

    //create the command object and store the sql query

    aCommand = new OleDbCommand("select Image from Images where KeyID = " + textBox1.Text, aConnection);

    MemoryStream ms = new MemoryStream();

    // 78 is the size of the OLE header for Bitmap images.

    // JPEG images adjust the header, search for it :-)

    // Execute the command and only ever return one result (Scalar)

    byte [] img = (byte[]) aCommand.ExecuteScalar();

    // Get a UTF7 Encoded string version

    Encoding u8 = Encoding.UTF7;

    string strTemp = u8.GetString(img);

    // Get the first 300 characters from the string

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

    int iPos = -1;

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

    {

    // Find the starting block of the image

    iPos = strVTemp.IndexOf(JPG_ID_BLOCK);

    }

    else

    {

    iPos = 78;

    }

    // From the position above get the new image

    if (iPos != -1)

    {

    ms.Write(img, iPos, img.Length - iPos);

    this.pictureBox1.Image = Image.FromStream(ms);

    }

    ms.Close();

     

     

    Then all you have to do is type in the index of the image you want to view in the database (the KeyID) and bob's your uncle ....  A wee side note, there is absolutely no error checking so it will crash if you do something wrong :-)  Byeee

    Wednesday, September 19, 2007 1:14 PM
  • Thanks for the post, this was really a big help.

     

    Do you ,by any chance, have a working VB code for this program? I copied your C# code and it worked but unfortunately upon converting it to VB.Net code, the strTemp value changes and iPos= -1 at the last IF statement. BMP files works just fine, only JPG files don't.

     

    thanks again!

    Friday, September 21, 2007 8:43 AM
  • Hi,

    I have a problem other way round

    Can you tell me how to store an image from a image control in an MS Access form to an MS Access DB 2003

    Regards
    Anand
    Tuesday, May 5, 2009 3:17 AM
  • If the image was create from a file you can write it to the database directly from the file. See the below forum link:

    http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvb/thread/7c8c0e45-027c-46c4-9690-64829bd6e7aa


    Paul ~~~~ Microsoft MVP (Visual Basic)
    Tuesday, May 5, 2009 1:36 PM