如何在不获取System.OutOfMemoryException的情况下处理/显示大图像



我正在尝试显示大约9000 x 9000像素的图像。图像存储在一个文件中。我用加载图像

BitmapImage image = new BitmapImage(new Uri(dialog.FileName));

在那句话之后,我冻结了图像。从那里,图像作为BitmapSource/BitmapImage在内部存储/传递给程序中的方法。

我已经编写了一些方法,试图使用MemoryStream对象(我把它放在using语句中)来调整/重新缩放图像。例如,一个这样的方法以以下语句开头。

using(MemoryStream stream = new MemoryStream())
{
PngBitmapEncoder e = new PngBitmapEncoder(); //BmpBitmapEncoder();
e.Frames.Add(BitmapFrame.Create(image));
e.Save(stream);
...
}

我经常会在该函数的e.Save(stream)行得到System.OutOfMemoryException()。如果我不尝试调整图像的大小,在创建使用image控件显示图像的窗口时,我会得到System.OutOfMemoryException()。

<Image Source="{Binding Image}" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="{Binding ImageWidth}" Height="{Binding ImageHeight}" />

现在,我知道OutOfMemory异常可能是不明确的,因为它们不一定意味着程序已经耗尽了它可以访问的RAM量。偶尔,程序会设法显示图像(尽管不久后它会抛出OutOfMemoryException),所以我不认为有问题的文件已损坏/格式无效或其他任何情况。

有没有更好的方法来处理WPF/.NET中的大型图像文件?如有任何建议,我们将不胜感激!

编辑:我现在更改了冻结图像的方式(我创建了一个冻结的副本,而不是冻结原始图像)。

如果您实际上不需要全分辨率来显示图像,您可以简单地设置BitmapImage的DecodePixelWidthDecodePixelHeight。不要同时设置这两个选项,以保持图像的纵横比。

var image = new BitmapImage();
image.BeginInit();
image.DecodePixelWidth = 900;
image.UriSource = new Uri(dialog.FileName);
image.EndInit();
image.Freeze();

相关内容

最新更新