测试C#GDI+双缓冲高效绘图--BufferedGraphicsContext

奥斯卡好的b、

 

测试C#GDI+双缓冲高效绘图
```

#region 截图
//获得当前屏幕的大小
Rectangle rect = new Rectangle();
rect = Screen.GetWorkingArea(this);
//创建一个以当前屏幕为模板的图象
Graphics g1 = this.CreateGraphics();
//创建以屏幕大小为标准的位图
System.Drawing.Image MyImage = new Bitmap(rect.Width, rect.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc();
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc();
//调用此API函数,实现屏幕捕获
BitBlt(dc2, 0, 0, rect.Width, rect.Height, dc1, 0, 0, 13369376);
//释放掉屏幕的DC
g1.ReleaseHdc(dc1);
//释放掉Bitmap的DC
g2.ReleaseHdc(dc2);
//以JPG文件格式来保存
MyImage.Save("Capture.jpg", ImageFormat.Jpeg);
System.Windows.Forms.MessageBox.Show("当前屏幕已经保存为capture.jpg文件!");
#endregion



#region C#GDI+双缓冲高效绘图 #region temp //Rectangle rectangle = e.ClipRectangle;//取出次窗体或者画布的有效区的矩形区域 //BufferedGraphicsContext GraphicsContext = BufferedGraphicsManager.Current;//获取程序住缓冲区域的BufferedGraphicsContext(双缓存类,此类用于提供双缓冲的功能)对象 //BufferedGraphics myBuffer = GraphicsContext.Allocate(e.Graphics, e.ClipRectangle);//获取缓冲区 // Graphics g = myBuffer.Graphics; //指定在呈现期间像素偏移的方式。 //g.PixelOffsetMode = PixelOffsetMode.HighQuality;//高质量低速度呈现 //指定是否将平滑处理(消除锯齿)应用于直线、曲线和已填充区域的边缘。 //g.SmoothingMode = SmoothingMode.HighQuality;// 指定高质量、低速度呈现。 //g.Clear(BackColor);//或者使用invalidate方法==有效区的擦除 //Pen bluePen2 = new Pen(Color.Blue); //LineDrawRoutine(g, bluePen2); //myBuffer.Render(e.Graphics); //将图形缓冲区的内容写入指定的 Graphics 对象。 //g.Dispose(); //myBuffer.Dispose(); //其实在C#里如果是在Form中绘图的话直接把Form的DoubleBuffered = true就可以了(利用winfrom窗体的默认双缓冲) //把所有的绘图放在一个picturebox里面绘制, //不要直接再在form里面绘 //SetStyle(ControlStyles.UserPaint, true); //SetStyle(ControlStyles.ResizeRedraw, true); //SetStyle(ControlStyles.AllPaintingInWmPaint, true); //SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //SetStyle(ControlStyles.Selectable, true); // 如果你在Form中绘图的话,不论是不是采用的双缓存,都会看到图片在更新的时候都会不断地闪烁,解决方法就是在这个窗体的构造函数中增加以下三行代码: //请在构造函数里面底下加上如下几行: //SetStyle(ControlStyles.UserPaint, true); //SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. //SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲 //参数说明: //UserPaint //如果为true,控件将自行绘制,而不是通过操作系统来绘制。此样式仅适用于派生自 Control的类。 //AllPaintingInWmPaint //如果为true,控件将忽略 WM_ERASEBKGND窗口消息以减少闪烁。仅当UserPaint 位设置为true时,才应当应用该样式。 //DoubleBuffer //如果为true,则绘制在缓冲区中进行,完成后将结果输出到屏幕上。双重缓冲区可防止由控件重绘引起的闪烁。要完全启用双重缓冲,还必须将UserPaint和AllPaintingInWmPaint样式位设置为 true。 #endregion #region MyRegion //在构造函数中加如下代码 //代码一: //SetStyle(ControlStyles.UserPaint, true); //SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. //SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲 //或代码二: //this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); //this.UpdateStyles(); #endregion #region MyRegion //.netframework提供了一个类BufferedGraphicsContext负责单独分配和管理图形缓冲区。每个应用程序域都有自己的默认 BufferedGraphicsContext 实例来管理此应用程序的所有默认双缓冲。大多数情况下,每个应用程序只有一个应用程序域,所以每个应用程序通常只有一个默认 BufferedGraphicsContext。默认 BufferedGraphicsContext 实例由 BufferedGraphicsManager 类管理。通过管理BufferedGraphicsContext实现双缓冲的步骤如下: //(1)获得对 BufferedGraphicsContext 类的实例的引用。 //(2)通过调用 BufferedGraphicsContext.Allocate 方法创建 BufferedGraphics 类的实例。 //(3)通过设置 BufferedGraphics.Graphics 属性将图形绘制到图形缓冲区。 //(4)当完成所有图形缓冲区中的绘制操作时,可调用 BufferedGraphics.Render 方法将缓冲区的内容呈现到与该缓冲区关联的绘图图面或者指定的绘图图面。 //(5)完成呈现图形之后,对 BufferedGraphics 实例调用释放系统资源的 Dispose 方法。 //BufferedGraphicsContext current01 = BufferedGraphicsManager.Current; //(1)初始化BufferedGraphicsContext 类的新实例 //BufferedGraphics bg01 = current01.Allocate(this.CreateGraphics(), this.DisplayRectangle); //(2) 使用指定的Graphics 的像素格式,创建指定大小的图形缓冲区。 //Graphics g01 = bg.Graphics;//(3)通过设置 BufferedGraphics.Graphics 属性将图形绘制到图形缓冲区 ////随机 宽400 高400 //System.Random rnd = new Random(); //int x, y, w, h, r, i; //for (i = 0; i < 10000; i++) //{ // x = rnd.Next(400); // y = rnd.Next(400); // r = rnd.Next(20); // w = rnd.Next(10); // h = rnd.Next(10); // g.DrawEllipse(Pens.Blue, x, y, w, h); //} //bg.Render();//(4)当完成所有图形缓冲区中的绘制操作时,可调用 BufferedGraphics.Render 方法将缓冲区的内容呈现到与该缓冲区关联的绘图图面或者指定的绘图图面。 ////bg.Render(this.CreateGraphics()); //bg.Dispose();//(5)完成呈现图形之后,对 BufferedGraphics 实例调用释放系统资源的 Dispose 方法。 #endregion public void TestBufferedGraphics01() { //完整的例子,在一个200 * 200的矩形框内绘制10000个随机生成的小圆 BufferedGraphicsContext current = BufferedGraphicsManager.Current; //(1)初始化BufferedGraphicsContext 类的新实例 //BufferedGraphics bg = current.Allocate(this.CreateGraphics(), this.DisplayRectangle); //(2)使用指定的Graphics 的像素格式,创建指定大小的图形缓冲区。 using (BufferedGraphics bg = current.Allocate(this.pbx01.CreateGraphics(), this.pbx01.DisplayRectangle)) //(2)使用指定的Graphics 的像素格式,创建指定大小的图形缓冲区。 { //随机 宽400 高400 using (Graphics g = bg.Graphics)//(3)通过设置 BufferedGraphics.Graphics 属性将图形绘制到图形缓冲区 { System.Random rnd = new Random(); int x, y, w, h, r, i; for (i = 0; i < 10000; i++) { x = rnd.Next(200); y = rnd.Next(200); r = rnd.Next(20); w = rnd.Next(10); h = rnd.Next(10); g.DrawEllipse(Pens.Blue, x, y, w, h); } bg.Render(); //bg.Render(this.pbx01.CreateGraphics());//(4)当完成所有图形缓冲区中的绘制操作时,可调用 BufferedGraphics.Render 方法将缓冲区的内容呈现到与该缓冲区关联的绘图图面或者指定的绘图图面。 //bg.Render(this.CreateGraphics()); bg.Dispose();//(5)完成呈现图形之后,对 BufferedGraphics 实例调用释放系统资源的 Dispose 方法。 } } } public void TestBufferedGraphics02() { //开辟一个缓冲区(如一个不显示的Bitmap对象),在其中绘制完成后,再一次性显示 using (Bitmap bt = new Bitmap(200, 200)) { using (Graphics bg = Graphics.FromImage(bt)) { System.Random rnd = new Random(); int x, y, w, h, r, i; for (i = 0; i < 10000; i++) { x = rnd.Next(200); y = rnd.Next(200); r = rnd.Next(20); w = rnd.Next(10); h = rnd.Next(10); bg.DrawEllipse(Pens.Blue, x, y, w, h); } //this.CreateGraphics().DrawImage(bt, new PointF(0, 0)); this.pbx01.CreateGraphics().DrawImage(bt, new PointF(0, 0)); } } } #endregion ```

 

posted @ 2024-05-28 11:50  龙骑科技  阅读(21)  评论(0编辑  收藏  举报