RenderTargetBitmap - Visual vector to bitmap
Written by Administrator   
Tuesday, 12 January 2010
Article Index
RenderTargetBitmap - Visual vector to bitmap
Practical rendering
Using Shapes

 

Drawing using Shapes

As well as rendering buttons and other controls we can also use the standard WPF UIElement graphics classes, i.e. Shapes, to effectively draw on the bitmap. The sequence of steps is exactly the same as for the button. First we create the Shape:

 Ellipse circle = new Ellipse();

Then we initialise it:

 circle.BeginInit();
circle.Height = 100;
circle.Width = 100;
circle.Stroke = Brushes.Black;
circle.StrokeThickness = 1.0;
circle.Margin=new Thickness(0,0,0,0);
circle.EndInit();

Finally we call Measure, Arrange and UpdateLayout:

 circle.Measure(new Size(200, 200));
circle.Arrange(
new Rect(new Size(200, 200)));
circle.UpdateLayout();

Again the size of the specified available areas just has to be bigger than the Visual object being measured and arranged.

It is also arguable that the BeginInit, EndInit calls are unnecessary for graphic Visuals and the call to Measure and UpdateLayout don't seemed to be essential - however the call to Arrange is critical.

We can also create a line to add to the circle:

 Line line = new Line();
line.BeginInit();
line.X1 = 60;
line.Y1 = 100;
line.X2 = 100;
line.Y2 = 20;
line.Stroke = Brushes.Magenta;
line.StrokeThickness = 1;
line.EndInit();
line.Measure(new Size(200, 200));
line.Arrange(new
Rect(new Size(200, 200)));

and finally we can render both to the bitmap.

 RTbmap.Render(circle);
RTbmap.Render(line);

What is on top of what depends on the order of drawing - so in this case the line overlays the circle.

linecircle

 

DrawingVisual

In a real application you would be well advised to write some general methods to render a UIElement without repeating all of the steps each time. However, if you want to draw on a bitmap you might like to use a completely different approach.

DrawingVisual is directly descended from Visual and not UIElement. Visual objects don't have the mechanisms to take part in the layout system - this is added at the UIElement level. What this means is that if you work with something closer to the Visual class, such as DrawingVisual, you can avoid the problems with the layout system altogether.

The only problem is that this involves using yet another part of the WPF system - drawing. The easiest way to see how this all works is by way of a simple example.

First we need a DrawingVisual:

 DrawingVisual DV = new DrawingVisual();

From this we create a DrawingContext:

 DrawingContext DC = DV.RenderOpen();

Now we can start to draw using vector drawing methods:

 DC.DrawEllipse(Brushes.Olive, null, 
new Point(50, 50), 20, 20);
DC.DrawLine(new Pen(Brushes.Red,1),
new Point(20,5),new Point(70,60));
DC.Close();

Notice that we have to close the DrawingContext before making any use of it. Also notice that DrawingVisual is a vector graphic - it simply stores a list of drawing instructions.

Finally we can render the DrawingVisual to the RenderTargetBitmap and this converts the drawing instructions into pixels:

 RTbmap.Render(DV);

There is no need to worry about calling Measure or Arrange as the DrawingVisual doesn't take part in the layout system.

Of course you can render DrawingVisuals, UIElements and any other objects descended from Visual using the same RenderTargetBitmap and generally create a bitmap from a range of sources.

Banner


WPF .NET Core - Creating Objects With XAML

If you've never encountered WPF (Windows Presentation Foundation) you are missing a versatile tool. This article is part of a series devoted to it. XAML can be confusing - especially if you think it i [ ... ]



WPF The Easy 3D Way

WPF provides a full 3D graphics experience without the need to master DirectX. It really is the easy 3D approach.



WriteableBitmap

WriteableBitmap gives you a bitmap object that you can modify dynamically - but exactly how to do this isn't always obvious.



WPF .NET Core - Inside Dependency Properties

One of the great mysteries of WPF is the strangely named "Dependency Properties". In this chapter we learn how dependency properties really work by creating a custom dependency property



ISupportInitialize and XAML

For a class to be instantiated by XAML it has to have a parameter-less constructor. This means that properties that might be essential to creating the instance can be initialized in any order and this [ ... ]


Other Articles

<ASIN:0672330334>

<ASIN:1590599543>

<ASIN:1430223812>

<ASIN:0470041803>



Last Updated ( Friday, 19 March 2010 )