Share via


How can I work around the fact tha Image.FromFile locks the file?

Question

Thursday, May 17, 2012 1:37 AM | 1 vote

Hello all,

I would like to grab some screenshots that I am creating automatically on a tool and load them into my C# application.

My approach looks like this:

 - Make the screenshot

- Wait for 6 seconds

- use Image.FromFile() in order to import the File.

However, I am getting errors as the file cannot be accessed by the tool making the screenshot anymore. How can I resolve this? (Everything works fine when I comment the Image.FromFile() line, but of cause not pictures are imported )

Thank you,

Benjamin

Info im http://social.msdn.microsoft.com/Forums/en-US/user

All replies (7)

Thursday, May 17, 2012 3:25 AM ✅Answered | 2 votes

Contrary to the warning that you must keep the stream open,  you can even dispose the stream:

      Image img;
      using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(imagePath)))
        img = Image.FromStream(ms);


Thursday, May 17, 2012 5:58 AM ✅Answered | 4 votes

In order to use fewer resources, try this too:

using( FileStream stream = new FileStream( path, FileMode.Open, FileAccess.Read ) )

{

         image = Image.FromStream( stream );

}


Thursday, May 17, 2012 1:47 AM | 1 vote

Hi Benjamin,

1. You can try to read the file stream into an byte array from read only mode

2. load the byte array into memory stream

3. use Image.FromStream to import the memory stream

It should work

Cheers,
Jacky

Jacky Yiu


Thursday, May 17, 2012 4:54 AM | 1 vote

Hi,

if its a single frame file and you want to use Image.FromFile (still), load it, copy it and dispose the first image-object:

              Bitmap bmp = null;

                using(Image img = Image.FromFile(@"C:\Users\...\Desktop\71f.tgi (2).png"))
                    bmp = new Bitmap(img);

Regards,

  Thorsten


Tuesday, May 22, 2012 11:01 PM

I haven't tried this solution as my files are png or jpeg and the user can choose.

Info im http://social.msdn.microsoft.com/Forums/en-US/user


Tuesday, April 2, 2013 8:28 PM

3 people are suggesting handling the stream by ourselves and using FromStream. Someone may have to be careful with that, and think about the lifetime of the resulting object. The solution may result in a trouble later: http://stackoverflow.com/questions/4803935/free-file-locked-by-new-bitmapfilepath/8701748#8701748


Tuesday, April 2, 2013 10:05 PM

Forget about the locks, use Image.FromStream(Stream,Boolean,False).  That is, use FromStream without validation.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
namespace WindowsFormsApplication1
{
  public partial class Form1 : Form
  {
    private Button Button1 = new Button();
    private Button Button2 = new Button();
    private PictureBox PictureBox1 = new PictureBox();
    public Form1()
    {
      InitializeComponent();
      Button1.Text = "Button1";
      Button2.Text = "Button2";
      Button2.Left = Button1.Right;
      PictureBox1.Bounds = new Rectangle(0, Button1.Bottom, this.ClientSize.Width, this.ClientSize.Height - Button1.Bottom);
      Button1.Click += Button1_Click;
      Button2.Click += Button2_Click;
      Button1.Parent = this;
      Button2.Parent = this;
      PictureBox1.Parent = this;
    }
      private void Button1_Click(object sender, EventArgs e)
    {
      using (Bitmap Bmp = new Bitmap(100, 100))
      {
        using (Graphics g = Graphics.FromImage(Bmp))
        {
          g.Clear(Color.Blue);
        }
        Bmp.Save("Test.png", ImageFormat.Png);
      }
      using (FileStream FS = new FileStream("Test.png", FileMode.Open))
      {
        PictureBox1.Image = Image.FromStream(FS, false, false);
      }
    }
    private void Button2_Click(object sender, EventArgs e)
    {
      using (Bitmap Bmp = new Bitmap(100, 100))
      {
        using (Graphics g = Graphics.FromImage(Bmp))
        {
          g.Clear(Color.Red);
        }
        Bmp.Save("Test.png", ImageFormat.Png);
      }
      using (FileStream FS = new FileStream("Test.png", FileMode.Open))
      {
        PictureBox1.Image = Image.FromStream(FS, false, false);
      }
    }
  }
}