C# 创建 Graphics 对象的三种方法详解

洛溪
洛溪
发布时间:2026-10-13 | 3人浏览过
原创

在 C# 开发中,进行图形绘制前必须获取 Graphics 对象。本文总结并详细解析了创建该对象的三种核心方法:利用 Paint 事件、调用 CreateGraphics 方法以及使用 FromImage 静态方法。文章提供了各方法的适用场景分析、操作入口、关键代码示例及完成状态的判断依据,帮助开发者根据实际需求选择最合适的绘图上下文获取方式。

结果与目标

在使用 C# 进行 Windows Forms (WinForms) 或其他支持 GDI+ 的应用程序开发时,开发者需要在屏幕上绘制线条、形状或文本,或在内存中修改图像。实现这些功能的前提是拥有一个有效的 Graphics 对象实例。本指南旨在明确三种标准获取途径及其最佳实践场景。

准备条件

  1. 开发环境:Visual Studio 或兼容的 C# 集成开发环境。
  2. 项目类型:Windows Forms 应用程序、WPF(需互操作)、控制台应用(配合特定库)或 ASP.NET Web Forms 等涉及服务端绘图的场景。
  3. 命名空间引用:确保代码文件顶部包含 using System.Drawing;。

真实操作顺序

第1步:利用 Paint 事件或重写 OnPaint 获取 Graphics

目的:在控件或窗体重绘(如最小化后恢复、被遮挡后显示)时获取最新的绘图表面,确保内容持久化。

入口:窗体类或自定义控件类的事件处理机制。

动作:

  • 方式 A:订阅 Paint 事件。在构造函数或初始化方法中为 Paint 事件添加处理器。在事件参数 PaintEventArgs 中提取 Graphics 对象。
// 窗体的 Paint 事件响应方法private void Form1_Paint(object sender, PaintEventArgs e){    // e.Graphics 是当前重绘区域的 Graphics 对象    using (Graphics g = e.Graphics)    {        // 在此处执行绘制操作,例如:        // g.DrawString("Hello", new Font("Arial", 10), Brushes.Black, 10, 10);    }}
  • 方式 B:重载 OnPaint 方法。直接继承并重写 OnPaint 虚方法。这是更面向对象的做法,推荐用于自定义控件开发。
protected override void OnPaint(PaintEventArgs e){    base.OnPaint(e); // 调用基类实现以保留默认绘制行为    using (Graphics g = e.Graphics)    {        // 自定义绘制逻辑    }}

重要参数:PaintEventArgs 包含 ClipRectangle(受影响的矩形区域)和 Graphics 属性。完成状态:当触发重绘时,e.Graphics 始终指向一个已初始化的有效绘图上下文。注意:在绘制完成后,如果不需要长期持有该对象,建议使用 using 语句包裹,尽管对于 e.Graphics,Dispose 通常由系统管理,但显式管理其他创建的 Graphics 实例是好习惯。

第2步:调用 CreateGraphics 方法即时获取

目的:在已存在的控件或窗体上立即进行一次性或非持久性的绘图操作。

入口:任何继承自 Control 的对象(如 Form, Button, Panel)。

动作:

  • 直接调用目标控件的 CreateGraphics() 方法。
// 在按钮点击事件或其他逻辑中调用private void Button1_Click(object sender, EventArgs e){    // 获取当前窗体的 Graphics 对象    Graphics g = this.CreateGraphics();    try    {        g.FillRectangle(Brushes.Red, 50, 50, 100, 100);    }    finally    {        // 必须手动释放资源,因为 CreateGraphics 创建的是新对象        g.Dispose();    }}

重要参数:无额外参数。风险提示与注意事项:此方法返回的 Graphics 对象对应于当前的屏幕状态。如果在鼠标移动或窗口调整过程中频繁调用,会导致闪烁和高负载。**关键点是必须调用 g.Dispose()**,否则会造成内存泄漏。此外,由于非重绘事件触发的绘制可能在下次重绘时被覆盖,因此不适合用于需要长期保存内容的绘图任务。

第3步:使用 FromImage 静态方法基于图像创建

目的:在内存中的图像(Bitmap 或 Image 对象)上进行编辑、绘图,而非直接在屏幕上绘制。

入口:已有的 Image 或其子类实例。

动作:

  • 加载图像文件或使用现有图像对象。
  • 调用 Graphics.FromImage() 静态方法。
// 假设当前路径下存在一张名为 "input.jpg" 的图片Image img = Image.FromFile("input.jpg");try{    // 创建基于该图像的 Graphics 对象    using (Graphics g = Graphics.FromImage(img))    {        // 可以在图片上写字、画图        Font font = new Font("Arial", 24);        Brush brush = new SolidBrush(Color.Red);        g.DrawString("Processed", font, brush, 10, 10);        // 保存修改后的图像        img.Save("output_processed.jpg");    }}finally{    if (img != null)        img.Dispose();}

重要参数:输入参数为 Image 类型。完成状态:成功创建可操作的绘图上下文的内存关联镜像。风险提醒:修改 Image 上的像素会直接影响原图数据(如果源是可变的 Bitmap)。务必先备份原始图像或在工作副本上操作,以免丢失数据。同时,Image.FromFile 会锁定文件直到图像对象被释放,建议尽早 Dispose 不再需要的图像。

完成判断与排错

  1. 有效性检查:所有获取到的 Graphics 对象在实例化时均不为 null。若为空,检查是否调用了未初始化的控件或错误的路径。
  2. 资源泄漏排查:使用 CreateGraphics 或 FromFile 生成的对象**必须**手动 Dispose。在 Visual Studio 的诊断工具中监控未释放句柄,若发现数量持续增加,通常是遗漏了 Dispose。
  3. 刷新问题:若使用 CreateGraphics 绘图后内容消失,是因为未触发重绘或未将绘图逻辑移至 OnPaint。对于简单标记,可强制调用 Invalidate() 触发重绘。

简要总结

选择哪种方法取决于具体的业务需求:需要持久化绘图且符合 UI 框架规范时使用 Paint 事件/OnPaint;需要简单的、临时的屏幕标注时使用 CreateGraphics(记得 Dispose);需要在内存中处理或生成新图像时使用 FromImage。理解这三者的区别能有效避免内存泄漏和绘图异常,提升 C# 图形编程的质量。

以上就是 C# 创建 Graphics 对象的三种方法的详细内容,更多关于 C# 图形编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表