Lord Gamez
Lord Gamez

Reputation: 319

Rendering drawingvisuals fast in WPF

Currently I have an image on a canvas that can I freely move around in my application on which I have 6 layers of DrawingVisuals rendered, but it seems to be pretty slow. I'm using a RenderTargetBitmap to render the visuals on. Is there a faster way to display the visuals on the image or on any other framework element I can freely move on the canvas?

xaml:

<Canvas>
    <Image Height="505" HorizontalAlignment="Left" Margin="0,0,0,0" Name="_MapImage" Stretch="Fill" VerticalAlignment="Top" Width="700" MouseLeftButtonDown="_MapImage_MouseDown" MouseWheel="_MapImage_MouseWheel" MouseLeftButtonUp="_MapImage_MouseUp" MouseMove="_MapImage_MouseMove" />
</Canvas>

code:

_renderRoutesBitmap = new RenderTargetBitmap((int)(_MapImage.Width), (int)(_MapImage.Height), 96, 96, PixelFormats.Default);

for (int i = 6; i < 8; ++i)
{
     if((layerCode / (int)Math.Pow(10,i) % 2) == 1)
     _renderRoutesBitmap.Render(_layers[i]); //takes too much time
}
_RouteImage.Source = _renderRoutesBitmap;

Upvotes: 6

Views: 3194

Answers (2)

gliderkite
gliderkite

Reputation: 8928

Display Visual objects using Render is not a good solution. If you have a Canvas and you want to render your visual you don't need to convert visuals into a bitmap, also if you if you make the conversion your image cannot be scaled by any amount without degrading quality (feature of the vector graphics). There is another possibility: create your own Canvas. I currently use this method, and have no problem to draw thousands of shapes. This is a very simple example:

public class DrawingCanvas : Panel
{


public List<Visual> visuals = new List<Visual>();


public void AddVisual(Visual visual)
{
    if (visual == null)
        return;
    this.visuals.Add(visual);

    base.AddVisualChild(visual);
    base.AddLogicalChild(visual);
}



public void RemoveVisual(Visual visual)
{
    if (visual == null)
        return;
    this.visuals.Remove(visual);

    base.RemoveVisualChild(visual);
    base.RemoveLogicalChild(visual);
}

}

Use DrawingCanvas instead of Canvas class.

Upvotes: 2

GETah
GETah

Reputation: 21409

I had to do a similar thing some time ago where I had to write my own GIS application. I had to draw thousands and thousands of drawing visuals, my findings were that RenderTargetBitmap is not a good choice for bitmap operations as it suffers from not using graphical hardware acceleration. Silverlight has a more suitable class; WriteableBitmap which allows your application to directly write into the GPU buffer. The only issue with this is that it is only available for Silverlight. If you want to stick to using a bitmap for your operations then you can use the equivalent of WriteableBitmap for WPF which is WriteableBitmapEx available here.

As you have only 6 drawing visuals in total, I suggest you move to using a higher level UI element such as Shapes and such.

Upvotes: 2

Related Questions