Implement faster graphics with WPF Canvas

I am trying to create a simple graphical application in WPF C #. The goal is to draw 10,000 * 10,000 rectangles of 4 pixels each.

I changed the OnRender method of the canvas to draw rectangles. Drawings are performed for fewer rectangles (for example, 50 * 50 or 100 * 100 rectangles of 4 pixels each), but it slows down as I increase the number. rectangles.

Below is my code:

protected override void OnRender(DrawingContext dc) { base.OnRender(dc); FillCells(dc); if (_ShowGrids) { DrawGrid(dc); // draw grid lines } } void FillCells(DrawingContext dc) { int cellSize=4; for (int i = 0; i < MaxRow; i++) { for (int j = 0; j < MaxColumn; j++) { dc.DrawRectangle(GetRectBrush(i,j), GetRectPen(i,j), new Rect(j * cellSize , i * cellSize , cellSize - 1, cellSize - 1)); } } } 

The above code takes more than a minute to draw 1000 * 1000 rectangles.

Is there a way to speed up this process? Is there anything else I can use instead?

Thanks.

+7
c # wpf canvas drawing
source share
6 answers

The goal is to draw 10,000 * 10,000 rectangles of 4 pixels each.

DO NOT draw them. So simple. It will be from 40 to 40 thousand pixels.

Most will not be visible. Therefore, they should not be drawn. Basically only draw those that are visible on the canvas. When resizing or scrolling, you redraw anyway, then do the same - just draw the ones that are visible.

Virtualization is the key to performance here. Take things out of the drawing cycle as early as possible. Things invisible to each definition do not need to be drawn at all.

The next option is not to use canvas. Try a bitmap. Prepare it in a separate thread, then draw it right away.

+11
source share

Then you should try StreamGeometry. http://msdn.microsoft.com/en-us/library/system.windows.media.streamgeometry.aspx

For complex geometries that are not needed that will be changed after they are created, you should consider using StreamGeometry rather than PathGeometry as performance optimization. Stream geometry is like PathGeometry, except that it can only be populated using procedural code. Its odd name refers to an implementation detail: use less memory (and less processor), its PathFigures and PathSegments are stored as a compact byte stream, and than a graph of .NET objects.

Quote from Adam Nathan's WPF Unleashed book.

+3
source share

You do not need to restore the brush for each iteration of the cycle, as they use the same color over and over:

 SolidColorBrush blueBrush = new SolidColorBrush(Colors.Blue) SolidColorPen bluePen = new SolidColorPen(blueBrush) for (int i = 0; i < MaxRow; i++) { for (int j = 0; j < MaxColumn; j++) { dc.DrawRectangle(blueBrush, bluePen, 1), new Rect(j * cellSize , i * cellSize , cellSize - 1, cellSize - 1)); } } 

This can speed up the cycle a bit.

+2
source share

One more hint over what everyone has already said, make sure that the pens and brushes are frozen - if you created the Freeze brush before using it (brushes from the Brushes (Brushes.White) class are already frozen).

+2
source share

The bitmap approach can be accelerated - BitmapSource has a Create method that accepts raw data either as an array or as a pointer to insecure memory. To set values ​​in an array should be a little faster than drawing real rectangles. However, you need to check the pixel formats to properly configure individual pixels.

+1
source share

Maybe try overlaying the canvas on VisualBrush.
To do this, visualBrush just add a 4 * 4 rectangle and repeat it in tile mode. Alternatively, you can simply add lines to it so that it does not overlap the edges of the rectangle ... of your choice :)

Your problem is to create a brush ... A test run showed that this code

 int limit = 10000 * 10000; var converter = new BrushConverter(); for (int i = 0; i < limit; i++) { var blueBrush = converter.ConvertFromString("Blue") as Brush; } 

it took 53 seconds. You are trying to create 100,000,000 brushes :) If it is patterned, use a patterned visual brush if it does not have a pattern ... perhapse is looking for another solution. The overhead of keeping many brushes in memory in Gigabytes

0
source share

All Articles