GDI+ Double Buffering and Flicker-Free Drawing in VB.NET

In this article you will learn how to use Double Buffering and Flicker-Free Drawing in GDI+.
  • 7432
Drawing on the Web works differently from drawing in the Windows Forms. On the Web we have many limitations, one of which is no pixelwise drawing support in the Web browser. Our approach 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 copies to the control. If the drawing operation is small and includes drawing only simple objects such as rectangle 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 provide 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 DrawLine method

    Private Sub DrawLine(ByVal g As Graphics)
        Dim width As Single = ClientRectangle.Width

        Dim height As Single = ClientRectangle.Height
        Dim partX As Single = width / 1000
        Dim partY As Single = height / 1000
        For i As Integer = 0 To 9999
            g.DrawLine(Pens.Blue, 0, height - (partY * i), partX * i, 0)
            g.DrawLine(Pens.Green, o, height - (partY * i), (width) - partX * i, 0)
            g.DrawLine(Pens.Red, 0, partY * i, (width) - partX * i, o)

    End Sub

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"
        Dim g As Graphics = Me.CreateGraphics()
        'Draw lines
        'Dispose of object

Figure 13.4 shows the output from Listing 13.9.

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.


FIGURE 13.4: Drawing lines in a loop

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

        Dim g As Graphics = Me.CreateGraphics()
        'Create a Bitmap object with the size of the form
        Dim curBitmap As New Bitmap(ClientRectangle.Width, ClientRectangle.Height)
        'Create a temporary Graphics object from the bitmap
        Dim g1 As Graphics = 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 Listing 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.


More Articles

© 2020 DotNetHeaven. All rights reserved.