Home > Net >  adding image into iamgelist using openfiledialog then calling it from database and slide showing it
adding image into iamgelist using openfiledialog then calling it from database and slide showing it

Time:08-31

i tried to add pictures using openfiledialog into an image list then save it in my Ms Access data base and call it in another form to show them in picture box by slide through them using a timer control but when i try to add picture's using open file dialog i get this error An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll Additional information: Out of memory.

here is my code

private void btnPicAdd_Click(object sender, EventArgs e)
        {            
            ofdTargetPic.Filter = "Image File (*.Gif;*.jpg)|*.Gif;*.jpg";
            ofdTargetPic.Title = "Add target picture";
            ofdTargetPic.Multiselect = true;
            ofdTargetPic.FileName = string.Empty;
            DialogResult result = ofdTargetPic.ShowDialog();
            if (result == DialogResult.OK)
            {
                picTargetchoose.SizeMode = PictureBoxSizeMode.StretchImage;
                foreach (var picture in ofdTargetPic.FileNames)
                {
                    imgltargetpic.Images.Add(Image.FromFile(picture));//error is here
                }
            }
        }

also if it's possible tell me with what format i can save the imagelist data in my data base i know the codes i just want to know what space should i open in my data base to save the data ( the format of imagelist output data)

here is the code for those who need to learn how to add the data into data base

OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Target.accdb");//this addres here is based on where you save your data base    
OleDbCommand cmd = new OleDbCommand();
    cmd.CommandText = "insert into tablename(tablefieldname,tablefieldname,...)values('"   textboxName.Text   "','"   textboxfamily.Text   "')";
    cmd.Connection = con;
    con.Open();
    cmd.ExecuteNonQuery();
    con.Close();

CodePudding user response:

Well, one would assume if you going to save the raw binary file in Access? Then the image control probably can figure out the format, but this suggests that you should ALSO at least have another column that saves the file name with extension.

And I would at least spend a cup of coffee time being REALLY sure you want to store the file in the database as opposed to in a folder, and then ONLY save the path name to the folder in the database table.

The reason for above are many, but this means:

If you ever want to adopt say sql server, then the data migration becomes very easy.

For any web based software - again having a path to a folder with images is VERY much less hassle and work.

Users can with great easy "copy files out" of that folder, search for file names in that folder, and use launch their favorite picture editor and viewing software. If you tuck away that file inside of the database, then you quite much lose use of any and all picture editors, and even picture organization and picture slide show software etc. And it makes it difficult for any other software to use such pictures.

Also, it is not clear if you are wishing to display the pictures in c# applcation, or that you want the pictures to display say in a access form? So this issue should be made clear here.

As noted, you want to save the filename with extension, since if you ever need to pull pictures out of the db, then you need the file extension (unless say you only ever allow one picture type to be saved).

You CAN use the oleDB type column in the Access db, or use memo. (but, if you save as binary into memo type column, then you need a do a string covert into byte[] BEFORE you shove into the image control.

So, I used oleDB type, and my database is this:

enter image description here

DO KEEP in mind, we are not at all using the oleDB format that Access uses. This choice is really simple a binary data blob.

The images without wee bit of code in VBA/MS-Access can be displayed, but I'm assume we display and using in c# a winform.

Ok, so say a form like this - real simple:

enter image description here

So, at top, we browse to a file - select it

This code:

    private void cmdBrowseFile_Click(object sender, EventArgs e)
    {
        OpenFileDialog MyFile = new OpenFileDialog();

        MyFile.ShowDialog();
        if (MyFile.FileNames.Length > 0)
        {
            txtFile.Text = MyFile.FileName;
            txtFileName.Text = Path.GetFileName(txtFile.Text);

            ShowPicFile(MyFile.FileName);

        }
    }

    void ShowPicFile(string sFile)
    {
        pictureBox1.Image = ByteToImage(File.ReadAllBytes(sFile));

    }


    public static Bitmap ByteToImage(byte[] blob)
    {

        Bitmap image;
        using (MemoryStream stream = new MemoryStream(blob))
            image = new Bitmap(stream);

        return image;

    }

So, if we browse to file - we display (not saved to db).

Say like this:

enter image description here

So, I take JUST the file name, shove into lower right box and then hit save to db

And it will add/save to db. That code is this:

    private void cmdSave_Click(object sender, EventArgs e)
    {
        // save picture as bytes to DB
        byte[] fData = File.ReadAllBytes(txtFile.Text);
        string strSQL =
            @"INSERT INTO MyPictures (FileName, PictureData)
            VALUES(@File, @Data)";
        OleDbCommand cmdSQL = new OleDbCommand(strSQL);
        cmdSQL.Parameters.Add("@File", OleDbType.VarWChar).Value = txtFileName.Text;
        cmdSQL.Parameters.Add("@Data", OleDbType.Binary).Value = fData;
        MyRstP(cmdSQL, false);

        // display in grid
        cmdSQL.CommandText = "SELECT ID, FileName FROM MyPIctures";
        cmdSQL.Parameters.Clear();
        dataGridView1.DataSource = MyRstP(cmdSQL);
        MessageBox.Show("saved");
    }

And now the new row appears in our grid. I can click on any row, then click show from DB. that code is this:

    private void cmdShow_Click(object sender, EventArgs e)
    {
        int pk = (int)dataGridView1.CurrentRow.Cells[0].Value;
        OleDbCommand cmdSQL =
            new OleDbCommand("SELECT ID, PictureData FROM MyPictures WHERE ID = @ID");
        cmdSQL.Parameters.Add("@ID", OleDbType.Integer).Value = pk;

        DataRow OneRow = MyRstP(cmdSQL).Rows[0];
        
        pictureBox1.Image = ByteToImage((byte[])OneRow["PictureData"]);                
    }

And my helper routines

    DataTable MyRstP(OleDbCommand cmdSQL, bool ReturnsData = true)
    {
        DataTable rstData = new DataTable();
        using (OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB))
        {
            using (cmdSQL)
            {
                cmdSQL.Connection = conn;
                conn.Open();
                    if (ReturnsData)
                        rstData.Load(cmdSQL.ExecuteReader());
                    else
                        cmdSQL.ExecuteNonQuery();
            }
        }
        return rstData;
    }

and

    public static Bitmap ByteToImage(byte[] blob)
    {
        Bitmap image;
        using (MemoryStream stream = new MemoryStream(blob))
            image = new Bitmap(stream);

        return image;
    }
  • Related