.Net Bitmap class constructor (int, int) and (int, int, PixelFormat) throws ArgumentException on perfectly good arguments

后端 未结 3 393
醉酒成梦
醉酒成梦 2020-12-10 15:27

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

void foo(Bitmap bmp1, Bitmap bmp2)
{
    Bitmap bmp3;
    if(something)
        bmp         


        
相关标签:
3条回答
  • 2020-12-10 15:41

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

    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.

    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.

    A 64-bit operating system doesn't have this problem. Be sure to take advantage of it with Project > Properties > Build tab, Platform target = AnyCPU and Prefer 32-bit = unticked. Also, WPF relies on WIC, an imaging library that's a lot smarter about allocating buffers for bitmaps.

    0 讨论(0)
  • 2020-12-10 15:51

    Check whether bmp1 or bmp2 has been Disposed (even if not null). See here:

    The Mysterious Parameter Is Not Valid Exception

    0 讨论(0)
  • 2020-12-10 16:02

    Anyone have any ideas?

    Wrap the call that is throwing ArgumentException with a try-catch(Exception ex) and step into the exception block to see the raw exception. It should give you more detail, like which argument is supposedly invalid.

    try
    {
        bmp3 = new Bitmap(bmp1.Width, bmp1.Height + bmp2.Height);
    }
    catch (Exception ex)
    {   
        throw;  // breakpoint here, examine "ex"
    }
    
    0 讨论(0)
提交回复
热议问题