使用WriteableBitmap 提供WPF图形绘制性能

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+ 相结合的方法进行图形绘制能数百倍以上提高图形绘制效率,解决大量数据绘制时的卡顿现象

猜你喜欢

转载自blog.csdn.net/u012846041/article/details/81667427