6

I want to be able to open/view a image (.jpg) without locking the file. Basically I have a program that lets the user choose a picture that will overwrite a picture. But the problem is that I display the image that is being overwritten. So how do I load an image without locking it?

This is the code I have to set the image right now

Image1.Source = new BitmapImage( new Uri( myFilePath ) ) ); 

myFilePath is equal to a string that would something like "C:\Users*\My Pictures\Sample.jpg"

H.B.
  • 166,899
  • 29
  • 327
  • 400
Usta
  • 271
  • 5
  • 14

3 Answers3

11

myBitmap.CacheOption = BitmapCacheOption.OnLoad is the line you're looking for. It "caches the entire image into memory at load time. All requests for image data are filled from the memory store." From MSDN

Something like this:

BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.UriSource = new Uri(myFilePath);
bmi.CacheOption = BitmapCacheOption.OnLoad;
bmi.EndInit();
Image1.Source = bmi;
Marcus
  • 5,407
  • 3
  • 31
  • 54
  • 2
    Make sure to add 'PresentationCore' to your references of your project or you will not be able to find the System.Windows.Media namespace. After adding that reference add using System.Windows.Media.Imaging; to the top of your project. ;) – Arvo Bowen Aug 19 '12 at 17:27
1

I think that StreamSource is the property you are looking for. You'd read the image into a MemoryStream, then set the MemoryStream as the value of the BitmapImage's StreamSource:

var memStream = new MemoryStream(File.ReadAllBytes(myFilePath));
Image1.Source = new BitmapImage() { StreamSource = memStream };

EDIT: I've tried this code, and it looks like you need to call BitmapImage.BeginInit and BitmapImage.EndInit around setting the Source:

var memStream = new MemoryStream(File.ReadAllBytes(@"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"));
var img = new BitmapImage();
img.BeginInit();
img.StreamSource = memStream;
img.EndInit();
myImage.Source = img;
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • Couldn't this cause memory leaks? If you wanted to change the image source, you couldn't Dispose() of the MemoryStream unless you kept a handle on the MemoryStream the whole time. – Marcus Jan 31 '12 at 23:25
  • 1
    If the memory stream is no longer rooted it will be garbage collected like any other managed object. That will happen if you assign some other object (presumably another memory stream) to the `BitmapImage`'s `StreamSource` – Chris Shain Jan 31 '12 at 23:28
  • That didn't work. It compiled and ran, but didn't it didn't load an the file into my WPF image. – Usta Feb 01 '12 at 00:11
  • I've checked the code, and determined that you need to call BeginInit and EndInit around setting the StreamSource. See edit above. – Chris Shain Feb 01 '12 at 02:59
  • Just found this answer and thought I'd give it a thumbs up since I was having some issues with image files getting locked up when they were read into the app. The code above has actually eliminated the problem. – Meh May 06 '12 at 11:48
0

When you open a file, you can also choose the share of the file to define its beaviour when another program requires that file :

(from msdn : http://msdn.microsoft.com/en-us/library/y973b725.aspx )

File.Open Method (String, FileMode, FileAccess, ** FileShare **)

Parameters
path
Type: System.String
The file to open.

mode
Type: System.IO.FileMode
A FileMode value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten.

access
Type: System.IO.FileAccess
A FileAccess value that specifies the operations that can be performed on the file.

* share
* Type: System.IO.FileShare *
A FileShare value specifying the type of access other threads have to the file.

GameAlchemist
  • 18,995
  • 7
  • 36
  • 59