1

This simple line of code to create a large resolution Bitmap produces a parameter is not valid error

        Bitmap bitmap = new Bitmap(6500, 4500);

There are some questions on SO that refers to memory bottleneck with GDI+ Ref C# "Parameter is not valid." creating new bitmap

I depend upon GDI+ to do image processing.Changing all the code is not practical.Some users report issues when processing large resolution images.How can i get over this issue? My machine has 4GB of Ram and i have tried building x64 version of the exe as well.

techno
  • 6,100
  • 16
  • 86
  • 192
  • @Hans Passant Could you please help me with this. – techno May 14 '20 at 07:19
  • Did you try to specify the `PixelFormat` as suggested in one of the answer to the question you reference? `new Bitmap(6500, 4500, PixelFormat.Format16bppRgb555)` I have 16GB and did not run into the error you are getting. – jira May 15 '20 at 12:38
  • @jira Can PixelFormat be used when creating Bitmap from File. – techno May 15 '20 at 18:30
  • To create Bitmap from file you use the `Bitmap (string filename)` constructor. The properties like bit depth etc are already given by the data. – jira May 15 '20 at 18:56
  • 1
    This should allocate (6500 x 4500 x 4) ~ 117M of RAM which should work fine so far. Are you sure you're showing us all code? I can't reproduce. Or what's you exact context / environment? – Simon Mourier May 16 '20 at 10:41
  • @SimonMourier I have tried replicating this again on the same machine.But this time the single line of code could not reproduce the issue.But when batch processing,the issue could be reproduced. – techno May 22 '20 at 14:47
  • It's probably a memory issue if you allocate many of bitmaps like this. If you want efficient help, you should put a whole reproducing code instead of a piece of code that works fine when isolated. – Simon Mourier May 22 '20 at 14:50
  • @SimonMourier It seems not to be an issue with memory.I have tried processing hundreds of high resolution images and it seems to work fine on the machine.But when it comes to this particular set of images, a parameter is not valid error is thrown.I will upload the sample images shortly. – techno May 26 '20 at 06:51

1 Answers1

1

It's all about memory usage. I have done a small test, and here is the result. I create only a 500x500 Bitmap, but many times, without disposing it:

private void button1_Click(object sender, EventArgs e)
{
    int maxIterations = 5000;
    bool exceptionOccured = false;
    for (int i = 0; i < maxIterations; i++)
    {
        Bitmap bitmap = null;
        try
        {
            bitmap = new Bitmap(500, 500);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception after " + i.ToString() + " iterations" + Environment.NewLine + ex.Message);
            exceptionOccured = true;
            break;
        }
        finally
        {
            //dispose the bitmap when you don't need it anymore (comment/uncomment to see the different result)
            //bitmap?.Dispose();
        }
    }
    if (!exceptionOccured)
    {
        MessageBox.Show("No exception after " + maxIterations.ToString() + " iterations");
    }
}

And the result (the bitmap was not disposed): TEST result with exception

The same code, but disposing the bitmap in the finally block:

private void button1_Click(object sender, EventArgs e)
{
    int maxIterations = 5000;
    bool exceptionOccured = false;
    for (int i = 0; i < maxIterations; i++)
    {
        Bitmap bitmap = null;
        try
        {
            bitmap = new Bitmap(500, 500);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception after " + i.ToString() + " iterations" + Environment.NewLine + ex.Message);
            exceptionOccured = true;
            break;
        }
        finally
        {
            //dispose the bitmap when you don't need it anymore (comment/uncomment to see the different result)
            bitmap?.Dispose();
        }
    }
    if (!exceptionOccured)
    {
        MessageBox.Show("No exception after " + maxIterations.ToString() + " iterations");
    }
}

And the result (the bitmap was disposed): TEST result without exception

  • So you're saying that the error message is misleading and that the actual error is a memory allocation error ? – ker2x May 21 '20 at 12:20
  • 1
    Right, also my sample demonstrates this. When the bitmap is disposed, the Exception does not occur. When the bitmap is not disposed, the Exception occurs at some point, depending on the available memory. The memory leak is not necessary generated by the bitmap itself. Could be another memory leak in the application, and when a new Bitmap is created it will crash. – Silviu Berce May 22 '20 at 13:14
  • Its indeed a memory issue.You do not need to create multiple images to replicate this.Just a single line of code in my example is enough in a low memory machine. – techno May 22 '20 at 14:45
  • It seems not to be an issue with memory.I have tried processing hundreds of high resolution images and it seems to work fine on the machine.But when it comes to this particular set of images, a parameter is not valid error is thrown.I will upload the sample images shortly – techno May 26 '20 at 06:51