Reputation: 319
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
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
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