c# - .Net 位图类构造函数 (int, int) 和 (int, int, PixelFormat) 在非常好的参数上抛出 ArgumentException

标签 c# .net

我有一些代码可以做这样的事情(不相关的部分被剪掉):

void foo(Bitmap bmp1, Bitmap bmp2)
{
    Bitmap bmp3;
    if(something)
        bmp3 = new Bitmap(bmp1.Width, bmp1.Height + bmp2.Height);
    else
        bmp3 = new Bitmap(bmp1.Width, 18000);
    (more stuff here that runs fine)
}

任何人大部分时间都运行良好。首先。随着项目的继续,它开始在新的位图行上失败。它给出的错误是:“ArgumentException 未处理。参数无效。”没有提到它有问题的参数或任何东西。我很难过。这是我确定知道的:

  1. bmp1 和 bmp2 从未为空 抛出此错误时。
  2. if 语句的存在 从来没有改变;它死了 就像没有一样频繁。
  3. 构造函数的两个例子都使用 抛出了这个错误。

我很想说这是一个内存错误,但它没有提到任何此类内容。前十几次这种情况发生的高度总计超过 18000(因此是上面的神奇数字)。认为这是我们系统的某种软屏障,我们只是将图像限制在那个高度,这使得异常在一段时间后就会消失。

对于一些样本数据,我现在看到的异常是 bmp1.Width 为 2550,bmp1.Height 为 6135,bmp2.Height 为 6285。

有人有什么想法吗?

最佳答案

GDI+ 不会生成很好的异常消息。你得到的异常是片状的,这个会在我的机器上可靠地生成它:

    private void button1_Click(object sender, EventArgs e) {
        var bmp = new Bitmap(20000, 20000);
    }

真正发生的是这个位图需要太多连续的非托管内存来存储位图位,超过了您的进程中可用的内存。在 32 位操作系统上,您只能希望分配大约 550 兆字节的内存块。从那里开始迅速走下坡路。

问题是地址空间碎片,程序的虚拟内存在不同的地址存储代码和数据的混合。总内存空间约为 2 GB,但最大的空洞比这小得多。您只能通过大量小分配消耗所有内存,大分配失败得更快。

长话短说:它试图告诉您无法支持您请求的尺寸。

64 位操作系统没有这个问题。请务必通过项目 > 属性 > 构建选项卡、平台目标 = AnyCPU 和首选 32 位 = 未勾选来利用它。此外,WPF 依赖于 WIC,这是一个图像库,在为位图分配缓冲区方面更加智能。

关于c# - .Net 位图类构造函数 (int, int) 和 (int, int, PixelFormat) 在非常好的参数上抛出 ArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1949045/

相关文章:

javascript - 使用 C# 在客户端转换为本地时间

c# - 在C#中,如何在编译时限制谁可以调用方法

.net - 缩小编码为 Base64 的 float 据字节

c# - 更新服务引用后项目未构建

c# - Properties.Settings 是否被缓存?

c# - 将部分构造函数参数传递给 caSTLe windsor 容器

c# - 尝试接受具有大文件的模型时出现 .net API 错误

c# - 带字符串数组的列表 (List<string[]>)

c# - 为什么 DotNetNuke 在发布 ajax 请求时将我注销?

c# - 如何调整图像大小并保持纵横比?