Skip to main content
 首页 » 编程设计

c#之System.Drawing.Bitmap(int32,int32) 参数在 WPF 中无效但在 win 窗体中无效

2024年02月13日34EasonJim

我正在将一些代码从 Windows 窗体程序移动到 WPF 程序,但我在以下代码中遇到了错误。

    //our private vars 
    private Bitmap bmp; 
    private Graphics g; 
 
    public NewFitnessCalculator() 
    { 
        bmp = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight); 
        g = Graphics.FromImage(bmp); 
    } 

错误表明 new System.Drawing.Bitmap 的参数无效,但据我所知它们都是 int(即使当直接转换为 int)。此外,这段代码在 Windows 窗体版本中运行良好——我不确定这是否是 WPF 的问题。 在这种情况下,Tools.MaxWidth/Height 是来自另一个类(也是 public static)的 public static ints。它们被初始化为200,然后分别设置为另一个位图的宽度和高度。

如有任何帮助,我们将不胜感激。

请您参考如下方法:

the memory usage is about 1,400 MB

尚不清楚这是工作集大小还是进程的 VM 大小。如果您使用任务管理器,那么您通常会查看工作集,即程序使用的 RAM 量。

在这种情况下,1,400 兆字节肯定会让您处于 32 位进程的危险区域。当进程的 VM 大小 逐渐接近 32 位进程可以寻址的最大虚拟内存量(2 GB)时,分配开始失败。您几乎可以肯定非常接近该限制。

会失败的分配类型是大分配,地址空间中没有足够大的空洞来满足请求的大小。位图当然是一个非常好的候选者,因为它们会为像素数据占用大量 VM 空间。

在这种情况下,您会期望出现 OutOfMemoryException。但是 GDI+ 会生成糟糕的异常,它假定真正的问题是您要求的位图太大。这并非完全没有优点,但当您创建 465 x 465 像素的位图时,它会有点难以接受。 Anyhoo,它生成“参数无效”异常消息而不是 OOM,归咎于您请求的大小。

不太清楚您最终是如何使用这么多内存的。但是,当您在 .NET 代码中使用 Bitmap 类时,这是一种非常常见的情况,您不能再忽略 Dispose() 方法的 .NET 类。一个强烈的暗示,你不关心这是你的评论,你预分配它作为 200x200 位图。这是一个非常糟糕的主意,您几乎肯定不会处理它。

因此,您需要做的第一件事就是彻底检查您的代码,并在不再使用时处理您的位图。如有必要,请使用内存分析器来查找泄漏。将 EXE 项目的平台目标设置从 x86 更改为 AnyCPU 是在 64 位操作系统上获取大量 VM 空间的一种非常简单的方法。从长远来看,您最终可能会使用 BitmapSource 和 WriteableBitmap 类替换此代码。