I use OpenFileDialog
to get the path of an image and then set it to my image source property imgSelected.Source = new BitmapImage(new Uri(filenameSteg, UriKind.Absolute));
in a WPF application.
The thing is, I need to open that file again later but I can't open it since the file is being used by another process ( System.IO.IOException
-> The process cannot access the file
pathToFile because it is being used by another process.
).
The code that needs to access it later it as follow :
bitmapSource = JpegBitmapDecoder.Create(File.Open(filenameSteg, FileMode.Open),
BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames[0];
This bitmapSource
is used to give that image to a WriteableBitmap
and from there I go through the pixels.
Is there any way to dispose of a File opened with an OpenFileDialog ?
I tried to cast to to IDisposable, to use a using block and so on but this thing is persistent.
EDIT :
1 - I tried this (@ctacke answer) :
using (var stream = File.Open(filenameSteg, FileMode.Open)){
bitmapSource = JpegBitmapDecoder.Create(stream, BitmapCreateOptions.None,
BitmapCacheOption.OnLoad).Frames[0];}
But it still gives me the error about the process being already in used by another process because even though it will be disposed after, I still am trying to open the same file (filenameSteg
) than I opened in the OpenFileDialog
. (Or at least, that's how I see it.)
2 - I then tried this (based on @ctacke recommended link:
using (FileStream fileStream = new FileStream(filenameSteg+1, FileMode.Create)){
MemoryStream memoryStream = new MemoryStream();
BitmapImage bi = new BitmapImage();
byte[] fileBytes = File.ReadAllBytes(filenameSteg);
memoryStream.Write(fileBytes, 0, fileBytes.Length);
memoryStream.Position = 0;
bi.BeginInit();
bi.StreamSource = memoryStream;
bi.EndInit();
bitmapSource = bi;}
Note : Notice that I here ask for filenameSteg +1
. That is because I wanted to test the rest of my method so I create a copy the file and simply added a 1 to its name. That being said, when using filenameSteg
for real, it gave me the same error about being already in used which I again suspect is that I still am asking to open the same image that was previously opened in the OpenFileDialog
.
3 - I thought of another approach which does not require me to dispose the opened image :
When I open the image for the first time in the OpenFileDialog
, I store the byte array of the image in a variable so I could create the WriteableBitmap
using the BitmapFactory
and the byte array.
// This is in the OpenFileDialog. It is where I stock the image "pixels" in a byte array.
bytesArrayImage = File.ReadAllBytes(filenameSteg);
//And then later when I needed the WriteableBitmap, I used the byte array and the BitmapFactory
//imgSelected being the Image containing the image I opened in the OpenFileDialog, I used it's
//width and height
wb = BitmapFactory.New(Convert.ToInt32(imgSelected.Width),
Convert.ToInt32(imgSelected.Height)).FromByteArray(bytesArrayImage);
The problem with this approach is that, some pictures works fine and I can use the byte array to create the WriteableBitmap
and go through it's pixels but in other cases it gives me an AccessViolationException
stating : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
. In other words, trying to bypass the dispose problem got me into another problem.
You should release the original image, something like this:
Next,
File.Open
returns a stream, which you need to explicitly release.See also: Load a BitmapSource and save using the same name in WPF -> IOException