DrawRectangle 画不出边框需确保 Pen 实例有效且 Width ≥ 1f;避免使用 CreateGraphics(),应响应 Paint 事件绘制;DrawString 模糊需设 PageUnit 为 Pixel 并用 TextRenderer.MeasureText;保存 PNG 要指定 Format32bppPArgb 并 Clear(Color.Transparent)。

Graphics.DrawRectangle 画不出边框?检查 Pen 是否为空或宽度为 0
常见错误是传入 null 的 Pen,或者用 new Pen(Color.Black, 0) —— GDI 里线宽为 0 表示“最细可显示线”,但某些 DPI 缩放或高分屏下会直接不可见。实际绘制必须确保 Pen 实例有效且 Width >= 1f。
- 用
new Pen(Color.Black, 1f)替代0,尤其在 .NET 6+ WinForms 高 DPI 模式下更稳定 - 避免复用已调用过
Dispose()的Pen,否则可能静默失败或抛ObjectDisposedException - 若从
Control.CreateGraphics()获取Graphics,记得手动Dispose(),否则 Pen 关联的 GDI 句柄可能泄漏
在 PictureBox 中绘图后不刷新?别直接用 CreateGraphics()
CreateGraphics() 返回的是临时设备上下文,绘图内容不会持久化,窗体最小化再还原、被其他窗口遮挡后重绘时就没了。正确做法是响应控件的 Paint 事件,在 PaintEventArgs.Graphics 上绘制。
- 订阅
pictureBox1.Paint += (s, e) => { e.Graphics.DrawEllipse(...); }; - 触发重绘用
pictureBox1.Invalidate()(标记区域需重绘),不是Refresh()(强制同步重绘,易卡顿) - 如果只是临时标注(比如鼠标圈选),可在内存 Bitmap 上绘制,再赋给
pictureBox1.Image,但注意频繁赋值会引发 GC 压力
DrawString 文字模糊或位置偏移?优先用 GraphicsUnit.Pixel + 精确测量
默认 DrawString 使用字体逻辑单位,受 Graphics.PageUnit 和 PageScale 影响,容易导致文字错位或模糊。Windows 渲染文本最稳的方式是统一设为像素单位,并用 Graphics.MeasureString 或更准的 TextRenderer.MeasureText 测量尺寸。
- 开头加
g.PageUnit = GraphicsUnit.Pixel; - 用
TextRenderer.MeasureText("text", font)替代MeasureString,它更贴近 GDI+ 实际渲染行为,尤其对中文和等宽字体 - 避免把
DrawString的PointF坐标直接设为整数,小数点后一位(如10.5f)能减少亚像素渲染抖动
保存绘图到 PNG 却出现黑底或透明丢失?Bitmap 构造时指定 PixelFormat
用 new Bitmap(width, height) 默认创建 PixelFormat.Format32bppArgb,看似支持透明,但若后续用 Graphics.FromImage() 绘制时未清空背景,或保存为 PNG 前没设置好 Alpha 通道,就会变黑底或丢透明。
- 明确初始化:
var bmp = new Bitmap(200, 100, PixelFormat.Format32bppPArgb);(PArgb 更快,适合绘图) - 绘制前先清空:
using var g = Graphics.FromImage(bmp); g.Clear(Color.Transparent); - 保存时确保目标格式支持 Alpha:
bmp.Save("out.png", ImageFormat.Png);,不要用Jpeg
真正麻烦的是跨线程操作 Graphics —— 它不是线程安全的,所有绘制必须在 UI 线程做。哪怕你用 Invoke 包了一层,也得确认 Graphics 对象本身没在别的线程里被缓存或复用。











