WPF与GDI+ 图形绘制不是完全割裂 开来的图形 绘制方法,当进行大批量图形数据绘制时,利用WriteableBitmap结合GDI+和WPF图形绘制方法,能够大幅提高图形绘制的效率。
关于WriteableBitmap对象的详细属性和方法请查阅MSDN相关文档,下例实现了在WPF中通过WriteableBitmap调用GDI+进行图形内容绘制,大大的提供了图形绘制效率。
利用WriteableBitmap调用GDI+图形绘制的主要方法有:
将WriteableBitmap的内容与Bitmap对象相关联;使用Graphics对象将图形绘制到内存中的Bitmap中,将WriteableBitmap的后台缓冲区图形内容复制到UI,示例代码如下:
//===========创建WriteableBitmap对象================
WriteableBitmap wBitmap = new WriteableBitmap(pixelWidth,pixelHeight,96,96,PixelFormats.Pbgra32,null);
//==========禁止图形内容输出到ui============================
wBitmap.Lock();
//============创建与WriteableBitmap后台缓冲数据关联的Bitmap 对象====================
Bitmap backBitmap = new Bitmap(pixelWidth, pixelHeight, wBitmap.BackBufferStride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, wBitmap.BackBuffer);
//==================获取Graphics绘图对象===============================
Graphics graphics = Graphics.FromImage(backBitmap);
graphics.Clear(System.Drawing.Color.Black);
//=============创建绘图路径=================================
GraphicsPath path = new GraphicsPath();
path.FillMode = FillMode.Winding;
//===============绘制网格线=========================
DrawBackLines(path);
//===============绘制多边形=========================
AddPolyLines(path, 100, 100);
AddPolyLines(path, 150, 150);
AddPolyLines(path, 200, 200);
System.Drawing.FontFamily fontFamily = new System.Drawing.FontFamily("微软雅黑");
graphics.DrawPath(new System.Drawing.Pen(System.Drawing.Color.Red, 0.5f), path);
//============绘制文本=================================
GraphicsPath fontPath = new GraphicsPath();
fontPath.AddString("HELLO", fontFamily, (int)FontStyle.Bold, 22, new Point(pixelWidth / 2, pixelHeight / 2), StringFormat.GenericDefault);
graphics.DrawPath(new System.Drawing.Pen(System.Drawing.Color.Blue, 2f), fontPath);
graphics.Flush();
wBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, pixelWidth, pixelHeight));
wBitmap.Unlock();
fontPath.Dispose();
fontPath = null;
path.Dispose();
path = null;
graphics.Dispose();
graphics = null;
backBitmap.Dispose();
backBitmap = null;
绘制背景网格的代码
protected void DrawBackLines(GraphicsPath gPath )
{
int interval = 3;
int lines = pixelWidth / interval;
if ((pixelWidth % interval) != 0)
lines += 1;
//PathGeometry pLines = new PathGeometry();
//pLines.FillRule = FillRule.EvenOdd;
//System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 0.5f);
//pen.Freeze(); //冻结可加快绘制速度
for (int i = 0; i <= lines; i++)
{
System.Drawing.Point tmp;
tmp = new System.Drawing.Point((i) * interval, 0);
if (tmp.X > pixelWidth)
tmp.X = pixelWidth;
System.Drawing.Point StartPoint = tmp;
tmp = new System.Drawing.Point((i) * interval, pixelHeight);
if (tmp.X > pixelWidth)
tmp.X = pixelWidth;
System.Drawing.Point EndPoint = tmp;
gPath.AddLine(StartPoint, EndPoint);
//=============关闭线段否则会和新绘制线段首尾相连===================================
gPath.CloseFigure();
}
lines = (int)pixelHeight / interval;
for (int i = 0; i <= lines; i++)
{
System.Drawing.Point tmp = new System.Drawing.Point(0, (i) * interval);
if (tmp.Y > pixelHeight)
tmp.Y = pixelHeight;
System.Drawing.Point StartPoint =tmp;
tmp = new System.Drawing.Point(pixelWidth, (i) * interval);
System.Drawing.Point EndPoint = tmp;
gPath.AddLine( StartPoint, EndPoint);
gPath.CloseFigure();
}
}
绘制多边形
protected void AddPolyLines(GraphicsPath gPath, int X, int Y)
{
//gPath.AddPolygon
for (int i = 0; i < 300000; i++)
{
int x = X + i * 2;
int y = Y + i * 2;
gPath.AddPolygon(new Point[] { new Point(x + 20, y), new Point(x, y + 20), new Point(x+20, y + 20) });
gPath.CloseFigure();
}
}
将绘制完成的WriteableBitmap 通过DrawingVisual绘制到UI,具体方法可 参见前面的博文。
通过测试采用WPF 与GDI+ 相结合的方法进行图形绘制能数百倍以上提高图形绘制效率,解决大量数据绘制时的卡顿现象