When I try to save a BitmapSource that I loaded earlier, a System.IO.IOException
is thrown stating another process is accessing that file and the filestream can
Add the following line to your loading code:
image.CacheOption = BitmapCacheOption.OnLoad;
This will load open the file, read it into memory, and close it all during image.EndInit. The default of BitmapCacheOption.Default has the odd behavior of opening the file, reading it into memory, but not yet closing it during image.EndInit.
Here is another solution, based upon the original loading code:
var image = new BitmapImage();
image.BeginInit();
// overwrite cache if already exists, to refresh image
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
// load into memory and unlock file
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = uri;
if (decodePixelWidth > 0) image.DecodePixelWidth = decodePixelWidth;
image.EndInit();
Now i'm not sure if this can be applied to BitmapImage but i had a very similar problem with saving a modified image to the original file in GDI+ here
The method of loading the image from file keeps a lock open on the file until the image object is disposed.
Maybe it's the same thing with bitmapimage.urisource. Without playing around could you copy the image in memory and dispose the original thus unlocking the file?
Setting CacheOption to BitmapCacheOption.OnLoad, will not solve your problem. I think there is a bug, but I had the same problem. Finally i loaded my image to a memory stream and disposed the BitmapImage before saving the image to the file.
Inspired by the comments I got on this issue, I solved the problem by reading all bytes into a memorystream and using it as the BitmapImage's Sreamsource.
This one works perfectly:
if (File.Exists(filePath))
{
MemoryStream memoryStream = new MemoryStream();
byte[] fileBytes = File.ReadAllBytes(filePath);
memoryStream.Write(fileBytes, 0, fileBytes.Length);
memoryStream.Position = 0;
image.BeginInit();
image.StreamSource = memoryStream;
if (decodePixelWidth > 0)
image.DecodePixelWidth = decodePixelWidth;
image.EndInit();
}