1

I'm in the process of moving some code from a windows forms programme to a WPF programme, and I've run into an error in the following code.

    //our private vars
    private Bitmap bmp;
    private Graphics g;

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

The error says that the parameters for the new System.Drawing.Bitmap are invalid, but as far as I can tell they are both int (problem persists even when directly cast as int). Also, this code was working fine in the windows forms version - I'm not sure if it's an issue with WPF. In this case Tools.MaxWidth/Height are public static ints from another class(also public static). They are initialised as 200, and then set to the Width and Height respectively of another bitmap.

Any help would be appreciated.

FireOak
  • 383
  • 3
  • 16
  • What are the values you are passing in, Have a look at this http://stackoverflow.com/questions/5801652/bitmap-while-assigning-height-width-crashes/5802113#5802113 – V4Vendetta Jul 02 '13 at 07:26
  • 1
    I've experienced the error with values of 465 - that shouldn't cause any errors due to being too large, should it? – FireOak Jul 02 '13 at 07:30
  • Do you have multiple `using` statements that reference classes with the same name? Try removing `System.Drawing` using statement and explicitly calling `System.Drawing.Graphics.FromImage` – keyboardP Jul 02 '13 at 07:38
  • The only two similar `using` statements I have are `System.Drawing` and `System.Drawing.Imaging` (If I remove either I get errors). Also, I don't want to copy my input image, just use its dimensions. – FireOak Jul 02 '13 at 07:45
  • have you tried casting both the width and height?, what is `Tools` – Sayse Jul 02 '13 at 07:58
  • I've tried `(int)Tools.MaxWidth/Height` and I got exactly the same error. `Tools` is a class that holds some global settings. – FireOak Jul 02 '13 at 08:05
  • Does it work if you use two ints as parameter directly? – LPL Jul 02 '13 at 08:16
  • Can you update your question with information on maxwidth/height? I just tried with `new System.Drawing.Bitmap(20, 20);` and thats fine – Sayse Jul 02 '13 at 08:30
  • I can't tell from the question whether this is a compile time error or a runtime error. Quacks like the latter, the **exact** error text, a stack trace for the exception as well as some hint about the memory usage of the program is required. – Hans Passant Jul 02 '13 at 08:32
  • @LPL no- it doesn't work with `int` as parameters directly for the few examples I tried – FireOak Jul 02 '13 at 08:43
  • @HansPassant I get the error whilst the programme is running - the exact text: System.ArgumentException was unhandled HResult=-2147024809 Message=Parameter is not valid. Source=System.Drawing The stack trace:http://pastebin.com/qrxwQPDS – FireOak Jul 02 '13 at 08:53
  • 2
    This exception can be raised when the program is very low on available unmanaged heap space. You left out the details of "some hint about the memory usage of the program". – Hans Passant Jul 02 '13 at 09:00
  • @HansPassant sorry - the memory usage is about 1,400 MB – FireOak Jul 02 '13 at 09:03

2 Answers2

5

the memory usage is about 1,400 MB

It isn't yet clear whether that's the working set size or the VM size of the process. If you use Task Manager then you typically look at working set, the amount of RAM being used by a program.

In which case 1,400 megabytes most certainly puts you squarely in the danger zone for a 32-bit process. Allocations start to fail when the VM size of a process creeps towards the maximum amount of virtual memory that a 32-bit process can address, 2 gigabytes. You are almost certainly very close to that limit.

The kind of allocations that will fail are large ones, there just isn't a hole big enough left in the address space to fit the requested size. A Bitmap is certainly a very good candidate since they can consume a lot of VM space for their pixel data.

You'd expect an OutOfMemoryException in this case. But GDI+ generates crappy exceptions, it assumes that the real problem is that you asked for a bitmap that's too large. That's not entirely without merit but gets to be a bit of a tough sell when you create a bitmap of 465 x 465 pixels. Anyhoo, it generates the "Parameter is invalid" exception message instead of OOM, blaming your requested size.

It isn't very clear how you ended up using so much memory. But it is a very common when you use the Bitmap class in .NET code, the one .NET class where you can no longer ignore the Dispose() method. A strong hint that you don't take care of this is your remark that you pre-allocate it as a 200x200 bitmap. That's a very bad idea, you almost certainly don't dispose that.

So the very first thing you need to do is thoroughly review your code and dispose your bitmaps when they are no longer in use. Use a memory profiler if necessary to find the leaks. Changing the Platform target setting of your EXE project from x86 to AnyCPU is a very simple way to get oodles of VM space on a 64-bit operating system. Long term, you'll probably end up replacing this code anyway, using the BitmapSource and WriteableBitmap classes.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
-1

There is BitmapEffect in WPF not Bitmap

Arushi Agrawal
  • 619
  • 3
  • 10
  • 1
    [Note: This API is now obsolete.](http://msdn.microsoft.com/en-us/library/system.windows.media.effects.bitmapeffect.aspx), plus its not the same thing as a bitmap – Sayse Jul 02 '13 at 08:25