0

My application is used to store scanned images, with additional information, to an SQL Database. Because I use a picturebox to accomplish this there is an issue I've become aware of with the picturebox holding open resources. This is preventing me from doing anything with the original file until I close my form. I have tried various ways to dispose of the picturebox with no success. Need help with the following code to release the resources held by the picturebox.

       using (OpenFileDialog GetPhoto = new OpenFileDialog())
        {
            GetPhoto.Filter = "images | *.jpg";
            if (GetPhoto.ShowDialog() == DialogResult.OK)
            {
                pbPhoto.Image = Image.FromFile(GetPhoto.FileName);
                txtPath.Text = GetPhoto.FileName;
                txtTitle.Text = System.IO.Path.GetFileNameWithoutExtension(GetPhoto.Fi‌​leName);
                ((MainPage)MdiParent).tsStatus.Text = txtPath.Text;
                //GetPhoto.Dispose();  Tried this
                //GetPhoto.Reset();  Tried this
                //GC.Collect(): Tried this
            }
        }

Saving the image to my database uses the following:

            MemoryStream stream = new MemoryStream();
            pbPhoto.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] pic = stream.ToArray();
Charles
  • 53
  • 7
  • There are several strategies to deal with that common issue. Using a stream to read the file (2nd link) is an common alternative to solution 1. - Note that using a `using` lause is the most reliable way to make sure the disposal actually happens.. – TaW Sep 21 '20 at 21:12
  • None of these solutions work! Any changes like using filestream to obtain the image causes errors when I try to save to database. I've read other posts but none are similar to what I'm trying to do. – Charles Sep 21 '20 at 21:56
  • _causes errors_ What errors? (Quote!) – TaW Sep 22 '20 at 00:17

1 Answers1

2

It's usually FromFile() that causes locking issues: (not the PictureBox itself)

The file remains locked until the Image is disposed.

Change:

pbPhoto.Image = Image.FromFile(GetPhoto.FileName);

To:

using (FileStream fs = new FileStream(GetPhoto.FileName, FileMode.Open))
{
    if (pbPhoto.Image != null)
    {
        Image tmp = pbPhoto.Image;
        pbPhoto.Image = null;
        tmp.Dispose();
    }
    using (Image img = Image.FromStream(fs))
    {
        Bitmap bmp = new Bitmap(img);
        pbPhoto.Image = bmp;
    }
}

This should make a copy of the image for use in the PictureBox and release the file itself from any locks.

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • This does not actually dispose the image you made from the stream, though, nor does it dispose the image put in `pbPhoto.Image`. Both of those are GDI+ object memory leaks. You need a second `using` for the `Image.FromStream` variable, and you need to store the original contents of `pbPhoto.Image` in a temp variable and dispose it afterwards if it's not null. – Nyerguds Nov 02 '20 at 09:00