C#GDI
GDI+(Graphics Device Interface Plus)是 C# 中用于 2D 图形绘制、图像处理和文字渲染的核心技术,主要通过System.Drawing
命名空间实现。以下是 GDI + 的核心知识点及实用示例:
一、核心知识点
核心对象
Graphics
:绘图 "画布",所有绘图操作的入口,可从PaintEventArgs
、Control.CreateGraphics()
或Image.GetGraphics()
获取。Pen
:用于绘制线条、轮廓(如矩形边框),可设置颜色、线宽、线型(实线、虚线等)。Brush
:用于填充图形内部,常见派生类:SolidBrush
(纯色)、LinearGradientBrush
(渐变)、TextureBrush
(纹理)。Font
与StringFormat
:Font
定义文本字体样式,StringFormat
控制文本对齐、换行等格式。Image
与Bitmap
:处理位图图像(加载、绘制、保存)。
坐标系统
默认以左上角为原点
(0,0)
,X 轴向右递增,Y 轴向下递增。可通过
Graphics.Transform
进行坐标变换(平移、旋转、缩放)。
绘图时机
图形需在
Control.Paint
事件中绘制,确保窗口重绘(如 resize、遮挡后恢复)时图形不丢失。强制重绘可调用
Control.Invalidate()
(触发 Paint 事件)。
资源管理
Pen
、Brush
、Font
等实现IDisposable
接口,需用using
语句或手动Dispose()
释放资源,避免内存泄漏。
二、实用示例
示例 1:基础图形与坐标变换
绘制带变换效果的图形(旋转、缩放):
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace GdiExamples {public class ShapeForm : Form{public ShapeForm(){Text = "GDI+ 图形与变换示例";Size = new Size(800, 600);Paint += ShapeForm_Paint;} private void ShapeForm_Paint(object sender, PaintEventArgs e){Graphics g = e.Graphics;// 抗锯齿,使图形边缘更平滑g.SmoothingMode = SmoothingMode.AntiAlias; // 1. 绘制基础图形// 实线矩形using (Pen solidPen = new Pen(Color.Blue, 3)){g.DrawRectangle(solidPen, 50, 50, 150, 100);} // 虚线椭圆using (Pen dashPen = new Pen(Color.Red, 2)){dashPen.DashStyle = DashStyle.Dash; // 设置为虚线g.DrawEllipse(dashPen, 250, 50, 150, 100); // 椭圆外接矩形} // 渐变填充多边形Point[] polygonPoints = { new Point(450, 50), new Point(550, 50), new Point(600, 120), new Point(500, 150) };using (LinearGradientBrush gradientBrush = new LinearGradientBrush(new Point(450, 50), new Point(600, 150), Color.Green, Color.Yellow)){g.FillPolygon(gradientBrush, polygonPoints);} // 2. 坐标变换:旋转并绘制矩形g.Save(); // 保存当前坐标状态g.TranslateTransform(150, 250); // 平移原点到(150,250)g.RotateTransform(30); // 旋转30度using (Pen pen = new Pen(Color.Purple, 2)){g.DrawRectangle(pen, 0, 0, 100, 60); // 基于新原点绘制}g.Restore(); // 恢复坐标状态 // 3. 坐标变换:缩放并绘制文本g.Save();g.ScaleTransform(1.5f, 1.5f); // 缩放1.5倍using (Font font = new Font("Arial", 12))using (SolidBrush brush = new SolidBrush(Color.Orange)){g.DrawString("缩放文本", font, brush, 50, 200);}g.Restore();} [STAThread]static void Main(){Application.EnableVisualStyles();Application.Run(new ShapeForm());}} }
示例 2:图像处理(加载、绘制、保存)
using System; using System.Drawing; using System.Windows.Forms; namespace GdiExamples {public class ImageForm : Form{private Image _image; // 存储加载的图片 public ImageForm(){Text = "GDI+ 图像处理示例";Size = new Size(800, 600);Paint += ImageForm_Paint;Load += ImageForm_Load; // 窗体加载时加载图片FormClosing += ImageForm_FormClosing; // 关闭时释放资源} // 加载图片(替换为你的图片路径)private void ImageForm_Load(object sender, EventArgs e){try{string imagePath = "test.jpg"; // 本地图片路径_image = Image.FromFile(imagePath);}catch (Exception ex){MessageBox.Show($"图片加载失败:{ex.Message}");}} private void ImageForm_Paint(object sender, PaintEventArgs e){if (_image == null) return; Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.AntiAlias; // 1. 绘制原始图片(缩放适应区域)Rectangle destRect = new Rectangle(50, 50, 400, 300); // 目标区域g.DrawImage(_image, destRect); // 绘制图片到指定区域 // 2. 添加水印文本using (Font font = new Font("微软雅黑", 24, FontStyle.Bold))using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, 255, 0, 0))) // 半透明红色{// 设置文本居中对齐StringFormat format = new StringFormat();format.Alignment = StringAlignment.Center;format.LineAlignment = StringAlignment.Center; g.DrawString("水印示例", font, brush, destRect, format);} // 3. 保存带水印的图片(可选)// using (Bitmap bmp = new Bitmap(800, 600))// {// using (Graphics bmpG = Graphics.FromImage(bmp))// {// bmpG.DrawImage(_image, destRect);// // 绘制水印(同上)// }// bmp.Save("watermarked.jpg");// }} // 释放图片资源private void ImageForm_FormClosing(object sender, FormClosingEventArgs e){_image?.Dispose();} [STAThread]static void Main(){Application.EnableVisualStyles();Application.Run(new ImageForm());}} }
示例 3:动态绘图(鼠标交互)
通过鼠标事件绘制自由曲线:
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace GdiExamples {public class DynamicDrawForm : Form{private List<Point> _points = new List<Point>(); // 存储鼠标轨迹点private bool _isDrawing = false; // 是否正在绘制 public DynamicDrawForm(){Text = "GDI+ 动态绘图示例";Size = new Size(800, 600);BackColor = Color.White; // 注册鼠标事件MouseDown += DynamicDrawForm_MouseDown;MouseMove += DynamicDrawForm_MouseMove;MouseUp += DynamicDrawForm_MouseUp;} // 鼠标按下:开始绘制private void DynamicDrawForm_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){_isDrawing = true;_points.Clear();_points.Add(e.Location); // 记录起点}} // 鼠标移动:记录轨迹private void DynamicDrawForm_MouseMove(object sender, MouseEventArgs e){if (_isDrawing){_points.Add(e.Location);Invalidate(); // 触发重绘}} // 鼠标释放:结束绘制private void DynamicDrawForm_MouseUp(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){_isDrawing = false;}} // 重绘时绘制曲线protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);if (_points.Count < 2) return; Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.AntiAlias; using (Pen pen = new Pen(Color.Black, 3)){g.DrawCurve(pen, _points.ToArray()); // 绘制平滑曲线}} [STAThread]static void Main(){Application.EnableVisualStyles();Application.Run(new DynamicDrawForm());}} }
三、注意事项
性能优化:频繁绘图时避免在
Paint
事件中创建大量对象(如Pen
、Font
),可提前创建并复用。抗锯齿:设置
Graphics.SmoothingMode = SmoothingMode.AntiAlias
使图形边缘更平滑。兼容性:
System.Drawing
在.NET Core/.NET 5 + 中需通过 NuGet 安装System.Drawing.Common
包(注意:Windows 兼容性更好,跨平台可能有限制)。
通过以上知识点和示例,可快速掌握 GDI + 的核心用法,适用于自定义控件、图表绘制、图片处理等场景。