在C#中用GDI+绘图,核心是获取
Graphics对象,然后调用它的绘图方法——不是直接“画”,而是“告诉Graphics去画”。关键在于时机和资源管理:必须在合适的地方(如
Paint事件)获取Graphics,并避免手动创建后忘记释放。
在窗体上实时绘制图形
最常用也最稳妥的方式是在窗体的
Paint事件中绘图。系统每次需要重绘(比如窗口被遮挡后恢复、调整大小)时,都会自动触发该事件,并传入已准备好的
Graphics对象。 双击窗体进入
Form1_Load前,先在设计器中选中窗体 → 属性面板 → 事件(闪电图标)→ 找到
Paint→ 双击生成事件处理方法 在生成的
Form1_Paint方法里,使用参数
e.Graphics进行绘制,例如:
e.Graphics.DrawRectangle(Pens.Red, 50, 50, 100, 80);
e.Graphics.FillEllipse(Brushes.Blue, 200, 60, 80, 60);不要在
Paint里调用
Refresh()或
Invalidate(),否则可能引发无限重绘循环
在Bitmap图片上离线绘制
如果想把图形画到内存中的图片(比如生成验证码、导出图表),就创建
Bitmap,再用
Graphics.FromImage()获得对应的
Graphics对象。 先创建位图:
Bitmap bmp = new Bitmap(400, 300);获取绘图表面:
using (Graphics g = Graphics.FromImage(bmp)) { ... }⚠️ 必须用
using确保释放资源,否则容易内存泄漏 绘制完成后,可保存为文件:
bmp.Save("output.png", ImageFormat.Png);或赋给
PictureBox.Image显示出来
基础绘图元素怎么写
GDI+绘图分“描边”和“填充”两类,对应不同方法和参数:
画线/矩形/椭圆轮廓:用DrawXXX系列,传
Pen对象(决定颜色、粗细、线型)
例:
g.DrawLine(Pens.Green, 10, 10, 100, 50);填充区域:用
FillXXX系列,传
Brush对象(纯色用
SolidBrush,渐变用
LinearGradientBrush等)
例:
g.FillRectangle(Brushes.Yellow, 0, 0, 200, 100);文字:
DrawString,需指定字体、画刷、位置(左上角坐标)
例:
g.DrawString("Hello", new Font("Arial", 12), Brushes.Black, 10, 10);
常见坑和建议
新手容易卡在这几个地方:
在Form_Load或构造函数里直接用
CreateGraphics()绘图 → 图形一闪就消失,因为没走重绘机制 自己new了
Graphics但没dispose → 程序跑一会儿就卡顿甚至崩溃 用
Control.CreateGraphics()获得的Graphics不推荐用于常规绘图,它绕过Paint流程,不可靠 需要动态更新画面(如动画)时,用
this.Invalidate()触发重绘,再在
Paint里画新状态,别硬刷
基本上就这些。GDI+不复杂,但资源管理和绘图时机容易忽略。抓住“Paint事件 + e.Graphics”这个主线,多数需求都能稳稳实现。
