问题:当在窗体中绘制较为复杂的图形对象时,常会出现闪烁的问题。
.NET Framework解决方案:
提供了双缓冲功能,原理是:当启用双缓冲时,所有绘制操作首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完成后,内存缓冲区直接复制到与其关联的绘图图面。因为在屏幕上只执行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁。
默认双缓冲:
在应用程序中使用双缓冲的最简便的方法是使用 .NET Framework 为窗体和控件提供的默认双缓冲。通过将 DoubleBuffered 属性设置为 true 或使用 SetStyle 方法可以为 Windows 窗体和所创作的 Windows 控件启用默认双缓冲。
手动管理缓冲的图形:
对于更多的高级双缓冲情形(如动画或高级内存管理),可以使用 .NET Framework 中的类实现自己的双缓冲逻辑。负责单独分配和管理图形缓冲区的类是 BufferedGraphicsContext 类。 每个应用程序域都有自己的默认 BufferedGraphicsContext 实例来管理此应用程序的所有默认双缓冲。 大多数情况下,每个应用程序只有一个应用程序域,所以每个应用程序通常只有一个默认 BufferedGraphicsContext。 默认 BufferedGraphicsContext 实例由 BufferedGraphicsManager 类管理。 通过调用 BufferedGraphicsManager.Current 属性可以检索对默认 BufferedGraphicsContext 实例的引用。 还可以创建一个专用的 BufferedGraphicsContext 实例以提高图形密集型应用程序的性能。
引用默认的BufferedGraphicsContext实例:
BufferedGraphicsContext myContext;
myContext = BufferedGraphicsManager.Current;
创建专用的BufferedGraphicsContext 实例:
BufferedGraphicsContext myContext;
myContext = new BufferedGraphicsContext();
// Insert code to create graphics here.
// On a non-default BufferedGraphicsContext instance, you should always
// call Dispose when finished.
myContext.Dispose();
手动呈现缓冲图形:
若要管理自己的缓冲图形,需要能够创建图形缓冲区并呈现其内容。通过调用 Allocate 可以创建与屏幕上的绘图图面关联的 BufferedGraphics 类的实例。 此方法创建一个与特定呈现图面(如窗体或控件)关联的 BufferedGraphics 实例。 创建 BufferedGraphics 实例后,可以将图形绘制到由该实例的 Graphics 属性表示的缓冲区。 执行所有图形操作后,可通过调用 Render 方法将缓冲区的内容复制到屏幕上。
手动显示缓冲的图形步骤:
1. 获得对 BufferedGraphicsContext 类的实例的引用
BufferedGraphicsContext myContext;
myContext = BufferedGraphicsManager.Current;
2. 通过调用 Allocate 方法来创建 BufferedGraphics 类的一个实例
BufferedGraphics myBuffer;
myBuffer = myContext.Allocate(this.CreateGraphics(),
this.DisplayRectangle);
3. 通过设置 Graphics 属性将图形绘制到图形缓冲区。
myBuffer.Graphics.DrawEllipse(Pens.Blue, this.DisplayRectangle);
4. 当完成所有图形缓冲区中的绘制操作时,可调用Render法将缓冲区的内容呈现到与该缓冲区关联的绘图图面或者指定的绘图图面
myBuffer.Render(); // or
myBuffer.Render(this.CreateGraphics());
5. 完成呈现图形之后,对 BufferedGraphics 实例调用释放系统资源的 Dispose 方法。
myBuffer.Dispose();
图形容器:GraphicsContainer 类
表示图形容器的内部数据。当使用 BeginContainer 和 EndContainer 方法保存 Graphics 对象的状态时使用此类。
使用图形容器:
Graphics 对象可被视为容器,因为它包含一组影响绘图的属性并且与设备特定的信息相链接。 通过调用该 Graphics 对象的 BeginContainer 方法可以在现有的 Graphics 对象中创建一个辅助容器。
1. 管理 Graphics 对象的状态:
Graphics 状态:
Graphics 对象不仅仅提供绘制方法,如 DrawLine 和 DrawRectangle。 Graphics 对象还维护图形状态,图形状态可划分为以下几类:
质量设置,变换,剪辑区域
(1) 质量设置:
Graphics 对象具有几个影响所绘项质量的属性。 例如,可设置 TextRenderingHint 属性以指定应用于文本的抗锯齿的类型(如果有的话)。 影响质量的其他属性是 SmoothingMode、 CompositingMode、 CompositingQuality 和 InterpolationMode。
(2) 变换
Graphics 对象维护两种应用到由 Graphics 对象绘制的所有项目的变换(世界变换和页变换)。 任何仿射变换都可存储在世界变换中。仿射变换包括缩放、旋转、反射、扭曲和平移。页变换可用于缩放和更改单位(例如,像素到英寸)。
(3) 剪辑区域
Graphics 对象维护应用于由 Graphics 对象绘制的所有项目的剪辑区域。可通过调用SetClip方法设置剪辑区域。
2. 使用嵌套的 Graphics 容器
Matrix 类: 封装表示几何变换的 3 x 3 仿射矩阵。
在 GDI+ 中,您可以在 Matrix 对象中存储仿射变换。 由于表示仿射变换的矩阵的第三列总是(0,0,1),因此在构造 Matrix 对象时,只需指定前两列中的 6 个数。