【发布时间】:2013-06-05 06:12:21
【问题描述】:
我正在 WPF 中使用适用于 .NET 的 FreeImage 包装器 (http://freeimage.sourceforge.net/) 制作一个简单的图像查看器
这里是代码
public static void OpenImage(string path)
{
_rawImage = new FreeImageBitmap(path);
BitmapSource bs = Utils.BitmapToBitmapSource(_rawImage.ToBitmap());
mainWindow.imageComponent.Source = bs;
mainWindow.imageComponent.Width = _rawImage.Width;
mainWindow.imageComponent.Height = _rawImage.Height;
}
[System.Runtime.InteropServices.DllImport("gdi32")]
static extern int DeleteObject(IntPtr o);
public static BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap source)
{
IntPtr ip = source.GetHbitmap();
BitmapSource bs = null;
try
{
bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
IntPtr.Zero, Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(ip);
}
return bs;
}
问题是显示图像时 ram 峰值和整体 ram 使用情况。我用于测试的图像是 5000x5000 jpeg。 FreeImage 报告它在内存中占用 70mb 的内存,这是正确的。如果我只运行这部分,我的应用程序大约需要 100mb(WPF 约 30 和图像 70):
_rawImage = new FreeImageBitmap(path);
但是当运行完整的代码时,内存会飙升到大约 280mb,这实在是太多了。在生产代码中,我显然可以处理所有未使用的项目,但最初的峰值太多了。我使用 IrfanView 进行图片浏览,同样的图片只占用 77mb 的内存。
我想要一些解决方案(如果有的话)来摆脱加载并将图像转换为 wpf Image 可以显示的格式所需的尖峰。如果可能的话,可能会进一步减少内存的使用。我使用大图像,如果加载一张图像需要 3 倍的内存,那就太糟糕了。我对 WPF 和这些东西很陌生,所以我可能缺少一些东西。
如果 WPF 中没有可能的解决方案,也许还有别的?我愿意接受建议。
我尝试搜索,但找不到任何解决我当前问题的方法。
非常感谢。
【问题讨论】:
-
我不知道 freeimage 是什么,但您在 WPF 中不需要任何这些。 WPF 对所有事情都有自己的机制,并不关心 GDI 或其他蹩脚的恐龙框架。您应该删除它并改用纯 WPF 的东西。
-
我需要 FreeImage,因为它支持许多图像格式,例如 raw、hdr 和 psd 等等。
-
Here 是使用 WPF 加载 RAW 的示例。 freeimage 的东西是基于恐龙 GDI 的东西,在 WPF 中不能很好地工作。
-
我的猜测是您正在将图像转换为内存中每像素 32 位的表示形式。 5000 * 5000 * 4 字节 = 200 MB。如果 IrfanView 使用 GDI,并且图像位于本地硬盘驱动器上,那么它可能会利用内存映射文件句柄来保持较低的内存需求。
-
This 似乎证实了我的怀疑。