views:

203

answers:

8

I have been working on some GDI+ code in .NET and have been learning my lessons the hard way. Simple things like:

  • What looks good on screen may not look nice on paper and vice versa
  • Caching too many objects can result in an OutOfMemoryException
  • Floats aren't exact

...and so on. I'm sure there is a lot more that experienced folk can add to this.

What are some good rules to follow when using GDI+ or any graphics library in general?

One useful tip per post will be nice. Thanks.

+5  A: 

Create objects as late as possible (Don't prematurely optimize/cache) and release them as early as possible (calling Dispose or wrapping in using statement if IDisposable).

Michael McCloskey
+2  A: 

Dont avoid using unmanaged calls, it can speed things up a lot when done correctly.

Mark Redman
+2  A: 

Careful when you transform between logical/screen coordinates. If done at the wrong time you can run out of precision and get some nasty drawing artifacts in return.

The last time this bit me, I was trying to calculate a new point in logical coordinates; those were already near the limit of precision though, so the new point was not quite what one would hope. Transforming sooner fixed it.

It is possible to get a similar problem by transforming to screen coordinates too soon, although an API which allows you to pass it floating point coordinates (which GDI+ does) tends to be much more robust against that.

Peter
+2  A: 

Don't draw more than you have to.

In general, drawing operations are more expensive than other calculations you'll be performing (especially in GDI+, which is a nice API but not the fastest drawing library ever). Spending a bit more time in your own code to avoid unnecessary drawing operations (eg. drawing the same thing more than once) is often well worth it.

Peter
+2  A: 

GDI Gotchas that have burned me a few times.

  • Clone doesn't clone() the underlying data clone(Rectangle, PixelFormat) does. So if you dispose of a clone(), the original object becomes unusable. Use new Bitmap() if you want two seperate bitmaps.
  • If you load an image FromFile that file is locked until the bitmap is disposed of (can't even be read).
  • When using DrawImage don't forget to set SmoothingMode, InterpolationMode and PixelOffsetMode or you will be surprised by the low quality of the image.
Kris Erickson
+1  A: 

Not strictly a GDI+ issue but remember this to save yourself a few hours of debugging:

One mistake I've made too often using GDI+ in .NET is to call Matrix methods on the Transform property of the Graphics object. Example (in C++/CLI):

g->Transform->Translate(100.0f, 250.0f);    // WRONG. Will not have any effect.

The getter of the Transform property only returns a copy of the matrix. So any methods called on this copy will not affect the value of the graphics transform. To manipulate the graphics transform, call one of the wrapper methods (MultiplyTransform, TranslateTransform, ScaleTransform, etc.) as shown below.

g->TranslateTransform(100.0f, 250.0f);
Vulcan Eager
+1  A: 

Be careful how you use regions: http://steveperks.com/post/Fun-With-GDI2b-Bugs.aspx

Vulcan Eager
+1  A: 

Hard limits for XY values in GDI+

Vulcan Eager