Drawing Bitmaps – DrawingImage and DrawingVisual
Drawing Bitmaps – DrawingImage and DrawingVisual
Wednesday, 20 January 2010
Article Index
Drawing Bitmaps – DrawingImage and DrawingVisual


DrawingContext – even lighter vectors

The GeometryDrawing classes are lightweight compared to the Shape classes but they are still full classes. The ultimate in lightweight vector drawing is provided by the DrawingContext that some Drawing classes provide. This approach to graphics will be familiar to any programmer "brought up" on the original Windows API and even the name sounds similar to the original DeviceContext or DC.

In this case however the drawing provided by the DrawingContext isn't immediate but part of the DirectX provided retained mode graphics that makes WPF different. That is when you draw using a DrawingContext you aren't drawing to the screen – nothing is being rendered. It's not until you have created the list of drawing instructions and actually render them that any drawing is actually performed.

To get a DrawingContext you need an object that can accept drawing commands. In this case the only suitable class is DrawingGroup and to get a DrawingContext you use its Open method. This clears anything that might have already been written to the DrawingGroup and returns a Drawing Context:

 DrawingContext MyDC = 

The DrawingContext has a range of drawing methods that can be use to add drawing commands. For example:

new Pen(Brushes.Yellow,1),
new Point(34,67),
new Point(120, 0));

Before you render the DrawingGroup you need to close the DrawingContext:


After this you can display the bitmap, i.e. a single yellow line, in the usual way:

 DrawingImage MyDrawingImage = 
new DrawingImage(MyDrawingGroup);
image1.Source = MyDrawingImage;

It is important to notice that a drawing context has a DrawDrawing method which allows you to draw any existing vector graphic Drawing object directly. For example:


will draw the DrawingGroup consisting of two lines as created earlier.

Using DrawDrawing you can have the best of both worlds – class based vector drawing and drawing methods.

Vector to WritableBitmap

The big problem with DrawingImage is that it descends directly from ImageSource which doesn't have the methods that you need to actually work with a bitmap at the pixel level. WriteableBitmap and RenderTargetBitmap do have everything you could need but as these are descended from BitmapSource you can't simply convert a DrawingImage into either class as they are not on the same branch of the class hierarchy.

There are a number of complicated juggling acts that can be performed to get a DrawingImage into either a RenderTargetBitmap or a WriteableBitmap. Fortunately it's quite easy when you know how.

The solution to the problem is the DrawingVisual class. This will render a drawing or any vector graphics you may want to create to a class that inherits from Visual – and anything that inherits from Visual can be rendered to a bitmap by RenderTargetBitmap. RenderTargetBitmap is more useful to us on two counts. The first is that it has a CopyPixel method which can be used to get at the pixel data. The second is that it is descended from BitmapSource and so can be used to create a WritableBitmap which in turn has methods that allow pixel manipulation.

For example, suppose you want to render MyDrawingGroup consisting of two lines as created earlier. All you have to do is first create a DrawingVisual:

 DrawingVisual MyDrawingVisual = 
new DrawingVisual();

Open its drawing context:

 DrawingContext MyDC = 

At this point you can use the drawing context's drawing methods to draw lines, ellipses and so on. You can also use its DrawDrawing method to draw any existing Drawing object. For example:


This draws the two lines in the DrawingGroup created earlier. When you are finished with the drawing context you have to close it as usual. Next you can complete the task by rendering the DrawingVisual to a RenderTargetBitmap:

MyRenderTargetBitmap =
new RenderTargetBitmap(

Now that you have a RenderTargetBitmap you can create a WriteableBitmap from it and start using it:

 WriteableBitmap MyWbmap = 
new WriteableBitmap(MyDrawingImage);
image1.Source = MyWbmap;

Once you have a WriteableBitmap bit map you should be able to do anything you want to.


Getting Started with WPF


WPF Windows Presentation Foundation is the new way to do forms and all things graphical in .NET. You can still use  Windows Forms but don't expect anything particularly new to be added to [ ... ]

Custom Bitmap Effects - HLSL

In the article Custom Bitmap Effects - Getting started we discovered how to work with HLSL in WPF. Now we are in a position to write more sophisticated shaders and  this means learning some more  [ ... ]

Inside Dependency Properties

Learn how dependency properties really work by creating a custom dependency property

RenderTargetBitmap - Visual vector to bitmap

RenderTargetBitmap will convert any Visual to a bitmap but sometimes it isn't quite as straighforward as just calling Render().

Simple WPF data binding

Find out how WPF data binding really works. It's not the binding object that matters - it's the binding expression.

Other Articles




Last Updated ( Friday, 19 March 2010 )

RSS feed of all content
I Programmer - full contents
Copyright © 2017 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.