GDI+在C#中不绑定图片,而是通过Graphics对象在窗体、位图或打印机等目标表面绘制;安全获取方式为:持久绘制用Paint事件中的e.Graphics,离屏绘制用Graphics.FromImage(bitmap),禁用CreateGraphics()用于UI持久显示,且所有Graphics必须显式Dispose或用using管理。

直接说结论:GDI+ 在 C# 中不是“绑定图片”,而是通过 Graphics 对象在目标绘图表面(如窗体、位图、打印机)上绘制;所谓“绑图”其实是获取一个可绘制的 Graphics 实例,最常用方式是调用 Bitmap.CreateGraphics() 或 Control.CreateGraphics(),但后者不推荐用于持久绘制——它不参与重绘机制,画面会在窗口刷新后丢失。
怎么安全地获取 Graphics 对象(避免闪屏/丢失/资源泄漏)
多数人一开始用 Control.CreateGraphics() 画完就以为成功了,结果一最小化再还原,图形没了。这不是 bug,是 GDI+ 的设计逻辑:控件的绘图表面是临时的,系统不负责保留你画的内容。
- 需要持久显示图形 → 必须在控件的
Paint事件中使用e.Graphics(PaintEventArgs提供),这是唯一受系统重绘生命周期管理的方式 - 想离屏绘制(比如生成带文字的缩略图)→ 创建
Bitmap,再用Graphics.FromImage(bitmap)获取绘图对象,画完后保存或赋给PictureBox.Image - 绝对不要长期持有
Graphics对象:它包装非托管资源,必须显式Dispose();用using最安全
DrawString 文字渲染模糊?字体和抗锯齿设置很关键
默认 Graphics.DrawString() 渲染的文字常发虚、边缘毛糙,尤其小字号或非整数坐标时。这不是字体问题,而是文本渲染模式没对齐 GDI+ 的像素栅格。
- 务必设置
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;(WinForm 下推荐)或AntiAliasGridFit(更平滑但稍慢) - 避免用浮点坐标绘制文字:传入
PointF容易错位,优先用Point或确保x/y是整数((int)Math.Round(x)) - 字体建议指定
GraphicsUnit.Pixel构造,避免 DPI 缩放干扰:new Font("Segoe UI", 12f, GraphicsUnit.Pixel)
DrawLine / DrawPolygon 线条粗细不准?注意 Pen 的宽度单位和对齐
设 Pen.Width = 1 却画出 2 像素宽的线,或者多边形轮廓偏移——大概率是 Pen.Alignment 和坐标未居中导致的。
-
Pen默认对齐方式是PenAlignment.Center,意味着线条中心落在你指定的坐标上;若画矩形边框,四条线各占半像素,整体变粗。要像素级精确,设pen.Alignment = PenAlignment.Inset并配合整数坐标 - 避免用
DrawRectangle(new Rectangle(x, y, w, h))后再DrawLine补边:重复绘制会加重边缘 - 开启
graphics.SmoothingMode = SmoothingMode.AntiAlias可柔化斜线,但对水平/垂直线无提升,反而可能轻微模糊
为什么从 Bitmap.CreateGraphics() 画完图,PictureBox 显示空白?
因为 Bitmap.CreateGraphics() 返回的是作用于位图内存的 Graphics,但此时位图本身没被任何控件引用;你画完了,却没把这张位图交给 UI 控件显示。
- 正确流程:创建位图 →
Graphics.FromImage(bitmap)→ 绘制 → 将bitmap赋值给PictureBox.Image(注意:赋值后别立刻Dispose位图,PictureBox 会持有引用) - 常见错误:画完后调用
bitmap.Save(...)再加载,既低效又可能因编码损失质量;直接复用位图对象即可 - 如果后续还要修改该图,别反复
FromImage:每次创建新Graphics都有开销,且需确保前一个已Dispose
真正难的不是画什么,而是搞清「谁拥有绘图表面」「谁负责重绘」「谁释放资源」。这三个问题没理清,图形要么一闪而过,要么内存缓慢增长,要么在高 DPI 屏幕上错位变形。


















