Question

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 cannot be opened.

If I only save whithout loading earlier, everything works fine.

The loading code:

BitmapImage image = new BitmapImage();

image.BeginInit();
image.UriSource = uri;

if (decodePixelWidth > 0)
image.DecodePixelWidth = decodePixelWidth;

image.EndInit();

the saving code:

using (FileStream fileStream = new FileStream(Directory + "\\" + FileName + ".jpg", FileMode.Create))
{
    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create((BitmapImage)image));
    encoder.QualityLevel = 100;
    encoder.Save(fileStream);
}

It seems like after loading the image data, the file is still locked an can never be overwritten while the application who opened it is still running. Any ideas how to solve this? Thanks alot for any solutions.

Was it helpful?

Solution

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();
}

OTHER TIPS

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();

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top