Hi Guys, i have a code to display an image in a picturebox called MemberPics. this image is also saved into a folder D:\\pictures. My problem is eventhough the image is saved successfully, am not able to retrieve it in another form. I always have FileNotFoundException even when I can physically see the file in the folder. please can anyone help me out. this is the code to display and save the image

private void btnpics_Click(object sender, EventArgs e)
        {

            OpenFileDialog openFD = new OpenFileDialog();
            //string chosen_file = "";

            openFD.Title = "Insert an image ";
            openFD.InitialDirectory = "c:";
            openFD.FileName = "";
            openFD.Filter = "JPEG Image|*.jpg|GIF Image|*.gif|PNG Image|*.png";


            if (openFD.ShowDialog() == DialogResult.Cancel)
            {
                MessageBox.Show("Operation cancelled !");
            }

            else
            {
                /*chosen_file = openFD.FileName;
                MemberPics.Image = Image.FromFile(chosen_file);
                //MemberPics.Image.Save("d:\\Pictures\\Chosen.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
                MemberPics.Image.Save("d:\\Pictures\\chosen_file", System.Drawing.Imaging.ImageFormat.Jpeg);*/
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.ShowDialog();
                    //string fileName = System.IO.Path.GetFileName(ofd.FileName);
                    fileName = System.IO.Path.GetFileName(ofd.FileName);
                    System.IO.File.Copy(ofd.FileName, "D:\\Pictures\\" + fileName);
                    MemberPics.Image = Image.FromFile("D:\\Pictures\\" + fileName);
                }

Later when i use this, the FileNotFoundException is thrown at me after successfuly saving a user info and i want to load it into another picturebox

display.Image = Image.FromFile("D:\\Pictures\\" + fileName);

If you have positively verified that the file you can see is named exactly the same as the file you are attempting to load...

Is it possible the file is still locked by a prior call to Image.FromFile? The MSDN documentation does not say what kind of lock is placed on the file (only that it remains locked until the image is disposed), but if there is a write lock then that would explain an exception, but not necessarily the one you are getting...

If you have positively verified that the file you can see is named exactly the same as the file you are attempting to load...

Is it possible the file is still locked by a prior call to Image.FromFile? The MSDN documentation does not say what kind of lock is placed on the file (only that it remains locked until the image is disposed), but if there is a write lock then that would explain an exception, but not necessarily the one you are getting...

how do I unlock the file before displaying it on another picturebox

how do I unlock the file before displaying it on another picturebox

You can destroy (Dispose() of) the previous Image that was loaded using the FromFile, or you can use this instead of FromFile to return an Image from a file:

public Image ImageFromFileNoLock(string fileName)
        {
            // Image.FromFile will hold a lock on the file until the image is destroyed,
            // so using a FileStream to load the file will release lock before returning image
            // because the stream gets closed...
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); 

            // Get image from stream...
            Image img = Image.FromStream(fs); 

            // Close/release the file...
            fs.Close();

            // return the image...
            return img;
        }

I don't understand what your code is doing. You are making 2 calls to openFileDiag.ShowDialog() .

Try something like this:

private void button2_Click(object sender, EventArgs e)
    {
      using (OpenFileDialog openFD = new OpenFileDialog())
      {
        openFD.Title = "Insert an image ";
        openFD.InitialDirectory = "c:";
        openFD.FileName = "";
        openFD.Filter = "JPEG Image|*.jpg|GIF Image|*.gif|PNG Image|*.png";
        openFD.Multiselect = false;

        if (openFD.ShowDialog() != DialogResult.OK)
          return;

        const string new_dir = @"C:\pictures\"; //I use C, not D
        string fName = System.IO.Path.Combine(new_dir, System.IO.Path.GetFileName(openFD.FileName));
        System.IO.File.Copy(openFD.FileName, fName);
        string msg = string.Format("Copied {0} to {1}",
          openFD.FileName,
          fName);
        MessageBox.Show(msg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
    }

@sknake: Thanks, I just changed it. But now, I want to store the fileName and the path into MySql database so that the can return the mysql string and load it into another picturebox bcos am now able to store the image from the picturebo (MemberPics) into mysql. Like this

string strSQL = "INSERT INTO memberinfo " + "(memberid,memberSname,memberFname, picture, fileName)" + "VALUES( '" + txtmid.Text + "','" + txtmSname.Text + "','" + txtFname.Text + "', '" + MemberPics.Image +"', '" + fileName+"')";

and called the picture and path to another picture box like this

string loadPic = "SELECT fileName from memberinfo";
display.Image = Image.FromFile("d:\\Pictures\\" + fileName + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg, loadPic);

Is that possible?, bcos I want to load the picture from mysql table which contains some other info about a particular user so that i can get the particular picture from that member info

Guys, i have been able to successfully save the filename called fileName to the table called memberinfo. i can see the filename in the table and also the picture with that name in the folder. Now I want to retrieve the filename from the table and add it to the folder so that my picturebox MemberPics can point to it and load an image from that file using this codes

string loadPic = "SELECT fileName from memberinfo";
string fullpath = string.Format("d:\\Pictures\\{0}", loadPic);
MemberPics.Image = Image.FromFile(fullpath);

but am getting a FileNotFound error. What cud be the problem cos the filename is in the table and the picture isn also in the folder d:\\pictures. please help

In line 2, all you are doing is appending your select statement to fullpath., which means you are trying to open file: "d:\\Pictures\\SELECT fileName from memberinfo", which does not exist I would imagine.

You need to retrieve "filename" from your database first, if that is where it is stored. You have the select statement (it appears) and I believe you said you saved the filename in your DB, right?

EDIT: Oh, I have seen you are also wanting to store and retrieve the actual image file from your database, which you have not yet achieved either?

Edited 7 Years Ago by DdoubleD: n/a

A lot of people are against storing binary data in an SQL Server. "Dont use it is a file system!". I personally don't share those opinions and often will store images in an SQL database when I can't ensure a UNC path will be accessible to all machines running the application.

So once you answer DdoubleD's question about storing the image inside of the database we should be better able to help you.

sknake: Now all i want to do is to retrieve the filename from the database and add it to my path to a folder. I am not sure I want to go through the long process of trying to retrieve the image from the database. So i need help with executing the query after successfully retrieving the filename from the database and then assign it to my picturebox Memberpics.

Try something like this. You need to use a "Where" clause in your SQL Query so you don't select every row since you probably only want the image for a particular user. Here is the test table I created:

--IF OBJECT_ID('MemberInfo', 'U') IS NOT NULL DROP TABLE MemberInfo
CREATE TABLE MemberInfo
(
  MemberId int PRIMARY KEY,
  MemberSname varchar(50),
  MemberFName varchar(50),
  Picture varchar(50),
  FName varchar(50)
)

And the code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;

namespace daniweb
{
  public partial class frmInsertImage : Form
  {
    const string connStr = @"Data Source=apex2006sql;Initial Catalog=ServManIRC;Integrated Security=True;";

    public frmInsertImage()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      using (OpenFileDialog openFD = new OpenFileDialog())
      {
        openFD.Title = "Insert an image ";
        openFD.InitialDirectory = "c:";
        openFD.FileName = "";
        openFD.Filter = "JPEG Image|*.jpg|GIF Image|*.gif|PNG Image|*.png";
        openFD.Multiselect = false;

        if (openFD.ShowDialog() != DialogResult.OK)
          return;

        const string new_dir = @"C:\pictures\"; //I use C, not D
        string fName = System.IO.Path.Combine(new_dir, System.IO.Path.GetFileName(openFD.FileName));
        if (File.Exists(fName))
          File.Delete(fName);
        System.IO.File.Copy(openFD.FileName, fName);
        string msg = string.Format("Copied {0} to {1}",
          openFD.FileName,
          fName);
        MessageBox.Show(msg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);

        //Insert into database
        int memberId = 1;
        string membersname = "knake";
        string memberfname = "scott";
        string picture = "my profile picture";

        InsertUpdateMemberInfo(memberId, membersname, memberfname, picture, fName);
      }
    }

    private void button2_Click(object sender, EventArgs e)
    {
      pictureBox1.Image = GetMemberImage(1);
    }



    private static void InsertUpdateMemberInfo(int MemberId, string MemberSname, string MemberFName, string Picture, string FName)
    {
      List<string> Sql = new List<string>();
      Sql.Add("IF EXISTS (Select * From MemberInfo (NOLOCK) Where MemberId = @MemberId)");
      Sql.Add("BEGIN");
      Sql.Add("  Update MemberInfo");
      Sql.Add("  Set ");
      Sql.Add("  MemberSname = @MemberSname,");
      Sql.Add("  MemberFName = @MemberFName,");
      Sql.Add("  Picture = @Picture,");
      Sql.Add("  FName = @FName");
      Sql.Add("  Where MemberId = @MemberId");
      Sql.Add("  Select @MemberId");
      Sql.Add("END ELSE");
      Sql.Add("BEGIN");
      Sql.Add("  Insert Into MemberInfo (MemberId, MemberSname, MemberFName, Picture, FName) Values (@MemberId, @MemberSname, @MemberFName, @Picture, @FName)");
      Sql.Add("  Select Cast(SCOPE_IDENTITY() as int)");
      Sql.Add("END");
      string query = GetText(Sql);
      using (SqlConnection conn = new SqlConnection(connStr))
      {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(query, conn))
        {
          cmd.Parameters.Add(new SqlParameter("@MemberId", SqlDbType.Int)).Value = MemberId;
          cmd.Parameters.Add(new SqlParameter("@MemberSname", SqlDbType.VarChar)).Value = MemberSname;
          cmd.Parameters.Add(new SqlParameter("@MemberFName", SqlDbType.VarChar)).Value = MemberFName;
          cmd.Parameters.Add(new SqlParameter("@Picture", SqlDbType.VarChar)).Value = Picture;
          cmd.Parameters.Add(new SqlParameter("@FName", SqlDbType.VarChar)).Value = FName;
          cmd.ExecuteNonQuery();
        }
      }
    }

    private static string GetText(List<string> Sql)
    {
      StringBuilder sb = new StringBuilder();
      foreach (string s in Sql)
        sb.AppendLine(s);
      return sb.ToString().Trim();
    }

    private static string GetMemberFilePath(int memberid)
    {
      const string query = @"Select FName From MemberInfo Where MemberId = @MemberId";
      using (SqlConnection conn = new SqlConnection(connStr))
      {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(query, conn))
        {
          cmd.Parameters.Add(new SqlParameter("@MemberId", SqlDbType.Int)).Value = memberid;
          string result = Convert.ToString(cmd.ExecuteScalar());
          return result;
        }
      }
    }
    private static Image GetMemberImage(int memberid)
    {
      string fileName = GetMemberFilePath(memberid);

      try
      {
        if (string.IsNullOrEmpty(fileName) || !File.Exists(fileName))
        {
          return null;
        }
      }
      catch (IOException)
      {
        return null;
      }

      return Image.FromFile(fileName);
    }
  }
}

Below is the code to read from the database into the controls i have on the form. everything is reading except the image. For that i get "Illegal characters in path" exception. can anyone help with the reader for the image?

public void loaddetails()
        {

            MySqlDataReader reader = null;

            try
            {
                accessDB.connection();
                //this.reset();

                String search = "SELECT memberSname,memberFname,memberOname,membersex,fileName FROM memberInfo WHERE memberid = '" + txtmid.Text + "'";

                accessDB.myCmd(search).ExecuteNonQuery();

                reader = accessDB.myCmd(search).ExecuteReader();

                reader.Read();
                //while ()
                //{
                    txtmSname.Text = reader["memberSname"].ToString();
                    txtFname.Text = reader["memberFname"].ToString();
                    txtmOname.Text = reader["memberOname"].ToString();
                    dateDOB.Text = reader["memberDOB"].ToString();
                    cmbGender.Text = reader["membersex"].ToString();
                    string img = reader["fileName"].ToString();

                    try
                    {
                        String path = ("d:\\Pictures\\" + img + ".jpg");
                        path = path.Trim(Path.GetInvalidFileNameChars());
                        path = path.Trim(Path.GetInvalidPathChars());
                        MemberPics.Image = Image.FromFile(path);
                    }
                    catch (Exception ex)
                    {

                        MessageBox.Show("Sorry, the pics could not be loaded " + ex.ToString());
                    }

                reader.Close();

I just want to read the filename and assign it to the path

Then you have illegal characters in the path of your filename, ie you probably inserted the wrong data in the table.

"C:\@$1298035@!#@%%%__@(\filename.txt" <-- illegal characters in path

But I can see the name of the image I selected in the table, so what cud be the problem and how can I solve it. any code or example will do Please

But I can see the name of the image I selected in the table, so what cud be the problem and how can I solve it. any code or example will do Please

Post your current code, indicating the line you get the error, and also indicate the values being used in the call.

1.
      public void loaddetails()
   2.
      {
   3.
       
   4.
      MySqlDataReader reader = null;
   5.
       
   6.
      try
   7.
      {
   8.
      accessDB.connection();
   9.
      //this.reset();
  10.
       
  11.
      String search = "SELECT memberSname,memberFname,memberOname,membersex,fileName FROM memberInfo WHERE memberid = '" + txtmid.Text + "'";
  12.
       
  13.
      accessDB.myCmd(search).ExecuteNonQuery();
  14.
       
  15.
      reader = accessDB.myCmd(search).ExecuteReader();
  16.
       
  17.
      reader.Read();
  18.
      //while ()
  19.
      //{
  20.
      txtmSname.Text = reader["memberSname"].ToString();
  21.
      txtFname.Text = reader["memberFname"].ToString();
  22.
      txtmOname.Text = reader["memberOname"].ToString();
  23.
      dateDOB.Text = reader["memberDOB"].ToString();
  24.
      cmbGender.Text = reader["membersex"].ToString();
  25.
      string img = reader["fileName"].ToString();
  26.
       
  27.
      try
  28.
      {
  29.
      String path = ("d:\\Pictures\\" + img + ".jpg");
  30.
      path = path.Trim(Path.GetInvalidFileNameChars());
  31.
      path = path.Trim(Path.GetInvalidPathChars());
  32.
      MemberPics.Image = Image.FromFile(path);
  33.
      }
  34.
      catch (Exception ex)
  35.
      {
  36.
       
  37.
      MessageBox.Show("Sorry, the pics could not be loaded " + ex.ToString());
  38.
      }
  39.
       
  40.
      reader.Close();

Above is the code and the error is in line 32: Illegal character in path

After running the code, I see path = "d:\\Pictures\\DA\0\0\0\0\0\0\0\0\0\0\0.jpg" instend of d:\\Pictures\\DA.jpg. Can someone help me to trim the unwanted characters from the path cos the fileName is DA so the path should read d:\\Pictures\DA.jpg. And I see only DA in the table not DA\0\0\0\0\0\0\0\0\0\0\0.

We should probably determine why you got those null characters ( \0 stored for your "filename" in the first place. What is the code you are using to INSERT or UPDATE the "filename" field?

I used this code to save the image to the folder

string chosen_file = "";
string file = "";
  chosen_file = openFD.FileName;
                string fileName = System.IO.Path.GetFileNameWithoutExtension(chosen_file);
                MemberPics.Image = Image.FromFile(chosen_file); 
               MemberPics.Image.Save(string.Format("d:\\Pictures\\{0}.jpg", fileName), System.Drawing.Imaging.ImageFormat.Jpeg); 
                file = fileName;

Then this code to insert the filename (fileName into the mysql database

string strSQL = "INSERT INTO memberinfo " + "(memberid,memberSname,memberFname, fileName)" + "VALUES( '" + txtmid.Text + "','" + txtmSname.Text + "','" + txtFname.Text + "',  '" + file +"')";

                    accessDB.myCmd(strSQL).ExecuteNonQuery();

which was successful. So after I was able to save the file into the folder and the fileName(not including the weird character) into the db, I expected to find only the filename not other characters attached to the fileName

I am going to BUMP on this one because nothing I can see to cause that string assignment to occur that way.

I assume you added the following lines to try to elliminate the problem:

path = path.Trim(Path.GetInvalidFileNameChars());
                        path = path.Trim(Path.GetInvalidPathChars());

but, you shouldn't need to be doing that either given the code I've seen. Also, I have not used those calls in a string.Trim before--have you tried it without those two lines?

Anyway, I've got somewhere I need to get to... Just post back a response and someone else will surely look into this before I get back.

The column in your database that holds the filename might be a char data type column (or wchar, etc), if you change it to varchar (or nvarchar, etc) then it will let you use variable length strings and not give you all those extra zeros.

The other choice (off the top of my head) is to change line 29 to this:

String path = ("d:\\Pictures\\" + img.Trim() + ".jpg");

Edit: (for some reason I think the char data type pads with spaces, not zeros, so the column data type couple be wrong. Also, I forget if Trim() removes zeros like this, you might need to call

img.Trim(new char[] {'\0'})

instead which specifically removes the zeros ... I think

Edited 7 Years Ago by mikiurban: Disclaimer: I just ate a giant chicken parmesan, I blame all errors to impending food coma :)

What in the world are you doing? Try to use the code I provided you and get it working. Then modify the code to do what you want it to .. and find out where it breaks.

sknake has a point (and no, he doesn't pay me to agree with him), calling .Replace() will fix this problem for now, but what you really want to do is understand why it's happening in the first place, or else your program will have a million Replace() commands. My money is on the data stored as char instead of varchar in the DB.

I doubt this is the problem, but you might want to be careful with this line:

string strSQL = "INSERT INTO memberinfo " + "(memberid,memberSname,memberFname, fileName)" + "VALUES( '" + txtmid.Text + "','" + txtmSname.Text + "','" + txtFname.Text + "',  '" + file +"')";

If any of those text boxes have an apostrophe in there, the insert will break. I suggest using

OleDbCommand cmd = new OleDbCommand(...);
cmd.Parameters.AddWithValue(...)

(or OdbcCommand, I forget which is for MS Access) to prevent any kind of query hacking shenanigans.

Comments
agreed++

sknake has a point (and no, he doesn't pay me to agree with him), calling .Replace() will fix this problem for now, but what you really want to do is understand why it's happening in the first place, or else your program will have a million Replace() commands. My money is on the data stored as char instead of varchar in the DB.

mikiurban has hit the nail on the head. On another note you need to handle DBNull.Value . I call Convert.ToString() on all string values brought back and the NULL will equate to string.Empty .

This article has been dead for over six months. Start a new discussion instead.