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

时间:2017-01-13 16:23:09

标签: c# .net wpf image

我正在尝试显示大约9,000 x 9,000像素的图像。图像存储在文件中。我用以下方式加载图像:

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控件显示图像的Window时获得System.OutOfMemoryException()。

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

现在,我知道OutOfMemory异常可能含糊不清,因为它们并不一定意味着程序已经耗尽了它可以访问的RAM量。有时候,程序会设法显示图像(虽然它会在抛出OutOfMemoryException之后不久),所以我不认为有问题的文件是否已损坏/格式无效或其他任何内容。

在WPF / .NET中使用大图像文件有更好的方法吗?任何建议将不胜感激!

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

1 个答案:

答案 0 :(得分:0)

如果您实际上不需要全分辨率来显示图像,则可以只设置BitmapImage DecodePixelWidthDecodePixelHeight。不要同时设置两者,以保持图像的宽高比。

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