净Bitmap类的构造函数(INT,INT)和(INT,INT,的PixelFormat)抛出ArgumentException的上完美的论据论据、抛出、函数、完美

2023-09-03 03:32:38 作者:纵遇

我有一些code,做这样的事情(不相关​​的位剪断):

I have some code that does something like this (Irrelevant bits snipped):

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)
}

Anywho大部分时间这个运行得很好。起初。随着项目的继续它开始在新的位图线失败。它给人的错误是:是的ArgumentException未处理的参数是无效的。有没有提到它的参数有一个问题或任何东西。我难倒。这是我知道的肯定的:

Anywho most of the time this ran fine. At first. As the project continued it started to fail on the new Bitmap line. The error it gives is: "ArgumentException was unhandled. Parameter is not valid." There's no mention of which parameter it has a problem with or anything. I'm stumped. Here's what I know for sure:

BMP1和BMP2从来没有空 当被抛出此错误。 if语句的presence有 从来没有一个差异;它死 正如经常没有。 构造函数使用的两个例子 纷纷抛出这个错误。 bmp1 and bmp2 have never been null when this error is thrown. The if statement's presence has never made a difference; it dies just as frequently without. Both examples of the constructor use have thrown this error.

我很想说这是一个内存错误,但它并没有提到任何的排序。第一个十次左右发生这种情况的高度总额超过18000(因此一个神奇的数字以上)。认定它是某种软障碍我们的系统,我们只是限制了图像在那个高度作出该例外一段时间后自行消失。

I'm tempted to say this is a memory error, except it doesn't mention anything of the sort. The first dozen times or so this happened the heights totalled over 18000 (hence the magic number above). Figuring it was some kind of soft barrier to our system, we just limited the images at that height which made the exceptions go away after a while.

对于一些样本数据,除我看现在有bmp1.Width在2550,bmp1.Height在6135和bmp2.Height在6285。

For some sample data, the exception I'm looking at right now has bmp1.Width at 2550, bmp1.Height at 6135 and bmp2.Height at 6285.

任何人有什么想法?

推荐答案

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

GDI+ does not generate very good exception messages. The exception you got is flaky, this one will generate it reliably on my machine:

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

什么是真正回事的是,这个位图需要太多连续的非托管内存来存储位图位,多是在过程中提供。在32位操作系统,你只能希望以后分配的内存块约550兆字节。从那里过得很快落山了。

What's really going on is that this bitmap requires too much contiguous unmanaged memory to store the bitmap bits, more than is available in your process. On a 32-bit operating system, you can only ever hope to allocate a chunk of memory around 550 megabytes. That goes quickly down-hill from there.

问题是地址空间碎片,你的程序的虚拟存储器存储的code和数据在不同地址的组合。总的内存空间大约是2千兆字节,但最大的洞比要小得多。你可以只消耗有很多小分配的所有记忆,大的失败快得多。

The issue is address space fragmentation, the virtual memory of your program stores a mix of code and data at various addresses. Total memory space is around 2 gigabytes but the biggest hole is much smaller than that. You can only consume all memory with lots of small allocations, big ones fail much quicker.

长话短说:它是想告诉你,你所要求的大小不能支持

Long story short: it is trying to tell you that the size you requested cannot be supported.

一个64位操作系统不存在这个问题。此外,WPF依赖于WIC,成像库,这是一个很多关于分配缓冲区位图更聪明。

A 64-bit operating system doesn't have this problem. Also, WPF relies on WIC, an imaging library that's a lot smarter about allocating buffers for bitmaps.

 
精彩推荐