Double Buffering and Flicker-Free Drawing

Do you remember the Web drawing method in Chapter 12? Drawing on the Web works differently from drawing in Windows Forms. On the Web we have many limitations, one of which is no pixelwise drawing support in the Web browser. So our approach in Chapter 12 was to convert our graphics objects into a temporary bitmap image and view the image in a Web browser.

Double buffering is a similar concept. You may have seen one of the frequently asked questions on GDI+ discussion forums: "How do we create flicker-free drawings"? The double buffering technique is used to provide faster, smoother drawings by reducing flicker. In this technique, all objects are drawn on an off-screen canvas with the help of a temporary image and a Graphics object. The image is then copied to the control. If the drawing operation is small and includes drawing only simple objects such as rectangles or lines, there is no need for double buffering (it may even degrade performance). If there are many calculations or drawn elements, performance and appearance may be greatly improved through the use of double buffering.

To prove the point, let's write an example. Listing 13.8 gives the code for a drawing method that draws several lines.

Listing 13.8 The DrawLines method

private void DrawLines(Graphics g)
 float width = ClientRectangle.Width;
 float height = ClientRectangle.Height;
 float partX = width / 1000;
 float partY = height / 1000;
 for (int i = 0; i < 1000; i++)
 0, height - (partY * i),
 partX * i, 0);
 height - (partY * i),
 (width) - partX * i,
 g.DrawLine(Pens.Red, 0,
 partY * i,
 (width) - partX * i,

To test our application, we will call it from a button click. The code for a button click event handler is given in Listing 13.9.

Listing 13.9 Calling the DrawLines method

// Create a Graphics object for "this"
Graphics g = this.CreateGraphics();
// Draw lines
// Dispose of object

Figure 13.4 shows the output from Listing 13.9.

Figure 13.4. Drawing lines in a loop


Now let's draw the same lines using a Bitmap object. We create a temporary Graphics object from a temporary image and call its draw and fill methods. Instead of calling DrawLine with respect to a form, we call DrawImage, which draws the image generated by the DrawLine method.

As Listing 13.10 shows, we create a Bitmap object in a buffer and send the entire buffer all at once using DrawImage. We add the code given in Listing 13.10 on the Bitmap Draw button click event handler.

Listing 13.10 Using double buffering to draw

Graphics g = this.CreateGraphics();
// Create a Bitmap object with the size of the form
Bitmap curBitmap = new Bitmap(ClientRectangle.Width,
// Create a temporary Graphics object from the bitmap
Graphics g1 = Graphics.FromImage(curBitmap);
// Draw lines on the temporary Graphics object
// Call DrawImage of Graphics and draw bitmap
g.DrawImage(curBitmap, 0, 0);
// Dispose of objects

Comparing the two methods given in Listings 13.9 and 13.10 reveals a significant difference in drawing performance. In Listing 13.9, drawing begins as soon as we hit the Simple Draw button and continues until it is done. By contrast, when we hit the Bitmap Draw button, drawing doesn't start immediately. This method actually draws on an in-memory Bitmap object, and when all drawing is done, it displays the bitmap.

GDI+: The Next-Generation Graphics Interface

Your First GDI+ Application

The Graphics Class

Working with Brushes and Pens

Colors, Fonts, and Text

Rectangles and Regions

Working with Images

Advanced Imaging

Advanced 2D Graphics



Developing GDI+ Web Applications

GDI+ Best Practices and Performance Techniques

GDI Interoperability

Miscellaneous GDI+ Examples

Appendix A. Exception Handling in .NET

GDI+ Programming with C#
GDI+ Programming with C#
ISBN: 073561265X
Year: 2003
Pages: 145 © 2008-2020.
If you may any questions please contact us: