C#下实现双缓冲描画高频曲线(GDI+结合GDI)
来源:互联网 发布:公交地图软件 编辑:程序博客网 时间:2024/05/01 00:20
由于项目需要,要使用c#描画高频实时曲线.
但是在C#下由于描画图像使用的是GDI+,描画效率很有问题.一旦曲线太多,就会造成CPU使用率直线上升,马上飙升到100%.
在GDI+下使用双缓冲也无济于事,双缓冲本身只会解决曲线多的时候全屏闪烁问题,但描画效率还是严重低下.
其间用过多种解决方案:DRECT3D,DRIRECT2D,GDI,,,,,等等等等
最后从效率出发,最终解决方案如下:
前台显示使用GDI,而后台描画则采用GDI+
后台采用10倍于前台窗口的BUFFER,每次向其中画一条线.然后通过一个RECT视口,每次向前台显示视口里的内容.否则每次重绘的代价太高.
这个方法实现的难点主要在于GDI和GDI+的结合部分,主要代码如下:
1.函数库:using 和 WIN32API函数
- using System.Runtime.InteropServices;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Drawing.Drawing2D;
- using System.Drawing.Text;
- [DllImport("gdi32")]
- public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
- [DllImport("gdi32")]
- public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
- [DllImport("GDI32.dll")]
- public static extern long BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
- [DllImport("GDI32.dll")]
- public static extern bool DeleteObject(IntPtr hObject);
2.声明对象
- public PictureBox _backgroundGraph;//被描画的控件对象
- //public Form _backgroundGraph;
- public Graphics _backgroundGraphic = null; // 背景Graphic
- public Graphics _backgroundRenderGraphic = null; // 双缓冲Graphic
- private Graphics _backgroundMemoryGraphic = null; // 内存Graphic
- public Graphics _backgroundDrawGraphic = null; // 描画Graphic
- private Bitmap _backgroundMemoryBitmap = null; // 内存Bitmap
- public BufferedGraphics _graphicsBuffer = null; // 双缓冲BufferedGraphics
- private IntPtr _memoryGraphicHdc; // 内存Graphic适用的引用
- private IntPtr _memoryBitmapHdc; // 内存Bitmap适用的引用
3.初始化对象
- public void InitDraw()
- {
- _backgroundGraph = pictureBox1;
- lock (_backgroundGraph)
- {
- if (null != _backgroundGraphic)
- {
- _backgroundGraphic.Dispose();
- }
- if (null != _graphicsBuffer)
- {
- _graphicsBuffer.Dispose();
- }
- if (null != _backgroundRenderGraphic)
- {
- _backgroundRenderGraphic.Dispose();
- }
- if (null != _backgroundMemoryBitmap)
- {
- DeleteObject(_memoryBitmapHdc);
- _backgroundMemoryBitmap.Dispose();
- }
- if (null != _backgroundMemoryGraphic)
- {
- DeleteObject(_memoryGraphicHdc);
- _backgroundMemoryGraphic.Dispose();
- }
- if (null != _backgroundDrawGraphic)
- {
- _backgroundDrawGraphic.Dispose();
- }
- // 背景Graphic
- _backgroundGraphic = _backgroundGraph.CreateGraphics();
- BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
- _graphicsBuffer = currentContext.Allocate(_backgroundGraphic, _backgroundGraph.ClientRectangle);
- // 双缓冲Graphic
- _backgroundRenderGraphic = _graphicsBuffer.Graphics;
- _backgroundRenderGraphic.Clear(Color.White);
- _backgroundRenderGraphic.SetClip(_backgroundGraph.ClientRectangle);
- // 内存Bitmap
- _backgroundMemoryBitmap = new Bitmap(_backgroundGraph.ClientRectangle.Width * 10, _backgroundGraph.ClientRectangle.Height, _backgroundRenderGraphic);
- // 内存Graphic
- _backgroundMemoryGraphic = Graphics.FromImage(_backgroundMemoryBitmap);
- _backgroundMemoryGraphic.Clear(Color.White);
- // 创建适用的绘图区
- _memoryGraphicHdc = CreateCompatibleDC(_backgroundMemoryGraphic.GetHdc());
- _memoryBitmapHdc = _backgroundMemoryBitmap.GetHbitmap();
- SelectObject(_memoryGraphicHdc, _memoryBitmapHdc);
- // 描画Graphic
- _backgroundDrawGraphic = Graphics.FromHdc(_memoryGraphicHdc);
- _backgroundDrawGraphic.SmoothingMode = SmoothingMode.HighQuality;
- _backgroundDrawGraphic.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
- _backgroundDrawGraphic.InterpolationMode = InterpolationMode.HighQualityBilinear;
- _backgroundDrawGraphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
- }
- }
4.使用GDI+描画曲线
- public void DrawSomething()
- {
- _backgroundDrawGraphic.DrawLine(System.Drawing.Pens.Black, 0, 0, 100, 100);
- }
5.使用bitblt向前台描画
- public void UpdateView()
- {
- IntPtr memHdc = _backgroundDrawGraphic.GetHdc();
- IntPtr renHdc = _backgroundRenderGraphic.GetHdc();
- BitBlt(renHdc, 0, 0, 100,
- 100, memHdc, 0, 0, 0xCC0020);
- _backgroundDrawGraphic.ReleaseHdc();
- _backgroundRenderGraphic.ReleaseHdc();
- _graphicsBuffer.Render(_backgroundGraphic);
- }
- C#下实现双缓冲描画高频曲线(GDI+结合GDI)
- C#下实现双缓冲描画高频曲线(GDI+结合GDI)
- GDI+ 双缓冲实现
- GDI+ 双缓冲实现
- GDIPLUS环境初始化以及与GDI结合实现双缓冲
- 双缓冲技术(C# GDI)
- c# 双缓冲绘图GDI
- 双缓冲技术(C# GDI)
- C# GDI+双缓冲技术
- 双缓冲技术(C# GDI)
- GDI双缓冲实现与GDI+双缓冲实现
- GDI双缓冲的实现
- c# GDI+的双缓冲问题
- C# GDI+双缓冲技术 及 资源
- C#结合GDI+实现橡皮筋技术
- 对话框 gdi+双缓冲实现代码
- 双缓冲技术(基于GDI+实现)
- 如何使用C#自带的GDI+双缓冲类BufferedGraphics实现双缓冲功能
- 手机时钟(加了表盘)代码
- zz 麻省理工教授箴言:怎样做研究生!
- IBM:服务共享平台 全面优化管理支撑系统
- 使用动态解析设置vpn
- 好久没推荐文章了
- C#下实现双缓冲描画高频曲线(GDI+结合GDI)
- Cannot access NLS data files问题的解决办法
- 正则表达式判断收藏
- 经典的子查询
- UVa Problem Solution: 10142 - Australian Voting
- 批处理文件bat 语法备忘
- 优先级问题。
- 一道JAVA题的解决
- 学术资料账号密码全集汇总(转)