C# 加载 BitmapSource 并在 WPF -> IOException 中使用相同的名称保存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/542217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:29:37  来源:igfitidea点击:

Load a BitmapSource and save using the same name in WPF -> IOException

c#wpfloadbitmapsave

提问by sdippl

When I try to save a BitmapSource that I loaded earlier, a System.IO.IOExceptionis thrown stating another process is accessing that file and the filestream cannot be opened.

当我尝试保存之前加载的 BitmapSource 时,System.IO.IOException会抛出 a 说明另一个进程正在访问该文件并且无法打开文件流。

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.

似乎在加载图像数据后,文件仍然被锁定并且永远不会被覆盖,而打开它的应用程序仍在运行。任何想法如何解决这个问题?非常感谢您提供任何解决方案。

采纳答案by sdippl

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.

受到我对这个问题的评论的启发,我通过将所有字节读入内存流并将其用作 BitmapImage 的 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();
}

回答by Crippeoblade

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

现在,我不知道这是否可以适用于BitmapImage的,但我曾与修改后的图像保存在GDI +的原始文件非常类似的问题在这里

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?

也许它与 bitmapimage.urisource 是一样的。如果不玩,您可以将图像复制到内存中并处理原始图像从而解锁文件吗?

回答by C. Dragon 76

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.Defaulthas the odd behavior of opening the file, reading it into memory, but not yet closing it during image.EndInit.

这将加载打开文件,将其读入内存,并在image.EndInit期间其全部关闭BitmapCacheOption.Default的默认值具有打开文件、将其读入内存、但尚未在image.EndInit期间关闭它的奇怪行为。

回答by mrtaikandi

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.

将 CacheOption 设置为 BitmapCacheOption.OnLoad,不会解决您的问题。我认为有一个错误,但我遇到了同样的问题。最后,我将图像加载到内存流并在将图像保存到文件之前处理了 BitmapImage。

回答by sdippl

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