图形概述
图形概述
GDI+(Graphics Device Interface图形设备接口)使程序员能够编写与设备无关的应用程序。
GDI+ 负责在屏幕和打印机上显示信息。
GDI+ API 通过一组部署为托管代码的类公开。 这组类被称为 GDI+ 的托管类接口。 以下命名空间构成托管类接口:
System.Drawing
System.Drawing.Drawing2D
System.Drawing.Imaging
System.Drawing.Text
System.Drawing.Printing
图形服务的三个类别
2D Vector Graphics(2D矢量图形)
二维矢量图形(如直线lines、曲线curves和图形figures)是由坐标系(Coordinate System)上的点集指定的基元。如直线由两个终点指定,矩形由一个左上角点、宽度和高度指定。贝赛尔曲线由四个控制点指定。
Rectangle:矩形的位置和大小。
Pen:线条颜色、宽度和样式等信息。
Graphics:可绘制线条、矩形、路径和其他图形的方法。
Brush:存储有关如何用颜色或图案填充闭合图形和路径的信息。
可以在图元文件中记录矢量图像,它是一系列图形命令。 GDI+ 提供用于记录、显示和保存图元文件的 Metafile 类。 使用 MetafileHeader 和 MetaHeader 类,可以检查存储在图元文件标头中的数据。
Imaging映像
某些种类的图片很难或不可能用矢量图形技术显示。
Bitmap:用于显示、操作和保存位图。
Typography版式
排版是以各种字体、大小和样式显示文本。
TextRenderer:提供使用GDI功能绘制文本。
图形界面的结构
GDI+ 的托管类接口包含大约 60 个类、50 个枚举以及 8 个结构。 Graphics 类是 GDI+ 功能的核心;它是实际绘制线条、曲线、数字、图像和文本的类。
关于GDI+托管代码
GDI+ 是 Windows 操作系统提供二维矢量图形、图像处理和版式的部分。 GDI+ 在 GDI(早期 Windows 版本包含的图形设备接口)的基础上进行了改进,添加了新功能和优化了现有功能。
GDI+ 托管类接口(一组包装器)是 .NET Framework 的一部分,.NET Framework 是一个用于构建、部署和运行 XML Web 服务和其他应用程序的环境。
直线、曲线和图形 (Lines 、Curves and Shapes)
矢量图形(Vector Graphics)概述
GDI+ 在坐标系统上绘制线条、矩形和其他形状。 可以从各种坐标系统中进行选择,但默认坐标系统的原点位于左上角,其中 x 轴指向右,y 轴指向下。 默认坐标系统中的度量单位是像素。
计算机显示器在称为图像元素或像素的矩形点阵列上创建显示。
从点(4,2)到点(12,8)绘制一条直线,效果如下图
GDI+提供下列构建基块:
- 直线(Lines)
- 矩形(Rectangles)
- 椭圆(Ellipses)
- 弧线(Arcs)
- 多边形(Polygons)
- 基数样条曲线(Cardinal splines)
- 贝赛尔曲线(Bezier splines)
使用Graphics对象进行绘制的方法
GDI+ 中的 Graphics 类提供以下方法来绘制上一列表中的项:DrawLine、DrawRectangle、DrawEllipse、DrawPolygon、DrawArc、DrawCurve(对于基数样条)和 DrawBezier。
Graphics 类的所有绘制方法都与 Pen 对象协同工作。
GDI+中的Pen、Line和Rectangle
- 绘制线段Line
private void Demo01_01(PaintEventArgs e)
{
//绘制线段
using (var myPen = new Pen(Brushes.Green))
{
e.Graphics.DrawLine(myPen, new Point(4, 2), new Point(12, 8));
}
}
- 构造笔Pen
//指定Pen的颜色和宽度
using (var redPen = new Pen(Color.Red, 2))
{
e.Graphics.DrawLine(redPen, 10, 20, 100, 200);
}
- 虚线(Dashed Lines)和线帽(Line Caps)
//指定虚线类型和线帽
using(var dashPen=new Pen(Color.Blue,20))
{
dashPen.DashStyle = DashStyle.Dash;
dashPen.StartCap = LineCap.ArrowAnchor;
dashPen.EndCap = LineCap.RoundAnchor;
dashPen.LineJoin = LineJoin.Bevel;
e.Graphics.DrawLine(dashPen, 50, 100, 300, 390);
}
- 绘制矩形(Rectangle)
var pen=new Pen(Color.SkyBlue, 2);
//绘制矩形
e.Graphics.DrawRectangle(pen, 20, 400, 100, 50);
pen.Dispose();
GDI+中的Ellipses和Arcs
var pen=new Pen(Color.PaleVioletRed, 2);
//绘制椭圆 (20,460,100,50)构成的矩形
e.Graphics.DrawEllipse(pen,20,460,100,50);
pen.Dispose();
//绘制弧
var rect = new Rectangle(20, 460, 100, 50);
var pen2=new Pen(Color.GreenYellow,2);
e.Graphics.DrawArc(pen2, rect, 30, 330);
pen2.Dispose();
GDI+中的Polygons
//绘制多段线
var myPointArray = new Point[]
{
new Point(150,30),
new Point(200,60),
new Point(180,80)
};
using (var myPen = new Pen(Color.Red, 3))
{
e.Graphics.DrawPolygon(myPen, myPointArray);
}
GDI+中的Cardinal Splines
//绘制多段线
var myCurveArray = new Point[]
{
new Point(250,30),
new Point(250,200),
new Point(300,110)
};
using (var myPen = new Pen(Color.Red, 1))
{//后面参数越大,越弯曲
e.Graphics.DrawCurve(myPen, myCurveArray, 0.5f);
e.Graphics.DrawCurve(myPen, myCurveArray, 1);
e.Graphics.DrawCurve(myPen, myCurveArray, 1.5f);
}
GDI+中的Bezier Splines
//绘制贝赛尔曲线
var startPt = new Point(400, 100);
var ctrlPt1 = new Point(500, 80);
var ctrlPt2 = new Point(520, 150);
var endPt = new Point(560, 180);
using(var myPen=new Pen(Color.Red,1))
{
e.Graphics.DrawBezier(myPen, startPt, ctrlPt1, ctrlPt2, endPt);
}
GDI+中的Graphics Path
//图形路径
var myGraphicsPath = new GraphicsPath();
myGraphicsPath.AddLine(0, 0, 30, 20);
myGraphicsPath.AddEllipse(20, 20, 20, 40);
myGraphicsPath.AddBezier(30, 60, 70, 60, 50, 30, 100, 10);
using (var myPen = new Pen(Color.Green, 2))
{
e.Graphics.DrawPath(myPen, myGraphicsPath);
}
//与前一个GraphicsPath是否相边
var combinePath = new GraphicsPath();
combinePath.AddPath(myGraphicsPath, connect);
combinePath.AddPath(myGraphicsPath2, connect);
GraphicsPath myGraphicsPath = new GraphicsPath();
Point[] myPointArray =
{
new Point(5, 30),
new Point(20, 40),
new Point(50, 30)
};
FontFamily myFontFamily = new FontFamily("Times New Roman");
PointF myPointF = new PointF(50, 20);
StringFormat myStringFormat = new StringFormat();
myGraphicsPath.AddArc(0, 0, 30, 20, -90, 180);
myGraphicsPath.StartFigure();
myGraphicsPath.AddCurve(myPointArray);
myGraphicsPath.AddString("a string in a path", myFontFamily,
0, 24, myPointF, myStringFormat);
myGraphicsPath.AddPie(230, 10, 40, 40, 40, 110);
using (var myPen = new Pen(Color.Green, 2))
{
e.Graphics.DrawPath(myPen, myGraphicsPath);
}
GDI+中的Brushes画笔和Filled Shapes实心形状
public void Demo01_06(PaintEventArgs e)
{
//纯色画笔
using (SolidBrush mySolidBrush = new SolidBrush(Color.Red))
{
e.Graphics.FillEllipse(mySolidBrush, 100, 100, 60, 40);
}
//阴影线画笔
using (HatchBrush myHatchBrush = new HatchBrush(HatchStyle.Vertical, Color.Blue, Color.Green))
{
e.Graphics.FillRectangle(myHatchBrush, 200, 100, 60, 40);
}
//纹理画笔
Image myImage = Image.FromFile("MyTexture.gif");
TextureBrush myTextureBrush = new TextureBrush(myImage);
e.Graphics.FillEllipse(myTextureBrush, 300, 100, 200, 150);
myTextureBrush.Dispose();
myImage.Dispose();
//渐变画笔
var myRectangle = new Rectangle(100, 200, 200, 100);
using (LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush(
myRectangle,
Color.Blue,
Color.Green,
LinearGradientMode.Horizontal))
{
e.Graphics.FillEllipse(myLinearGradientBrush, myRectangle);
}
//中心向外渐变
myRectangle = new Rectangle(450, 200, 200, 100);
GraphicsPath path = new GraphicsPath();
path.AddEllipse(myRectangle);
using (var brush = new PathGradientBrush(path))
{
brush.CenterColor = Color.White;
brush.SurroundColors = new Color[] { Color.Blue };
e.Graphics.FillEllipse(brush, myRectangle);
}
path.Dispose();
//中心向外多个颜色渐变
// 定义三角形的三个顶点
PointF[] points = {
new PointF(150, 350), // 顶点1
new PointF(50, 500), // 顶点2
new PointF(250, 500) // 顶点3
};
// 创建路径并添加三角形
using (GraphicsPath path2 = new GraphicsPath())
{
path2.AddPolygon(points);
// 创建PathGradientBrush并设置路径
using (PathGradientBrush pgb = new PathGradientBrush(path2))
{
// 设置中心颜色
pgb.CenterColor = Color.Red;
// 设置顶点颜色
pgb.SurroundColors = new Color[] { Color.Green, Color.Blue, Color.Yellow };
// 填充三角形
e.Graphics.FillPolygon(pgb, points);
}
}
}
GDI+中的开放和闭合曲线
GDI+ 中的 Graphics 类提供以下方法来填充闭合形状和曲线:FillRectangle、FillEllipse、FillPie、FillPolygon、FillClosedCurve、FillPath 和 FillRegion。
using (var mySolidBrush = new SolidBrush(Color.Green))
using (var myPen = new Pen(Color.Red,2))
{
//绘制弧线和填充扇形图
e.Graphics.FillPie(mySolidBrush, 0, 0, 140, 70, 0, 120);
e.Graphics.DrawArc(myPen, 0, 0, 140, 70, 0, 120);
//绘制和填充闭合曲线
Point[] myPointArray =
{
new Point(0, 0),
new Point(60, 20),
new Point(40, 50)
};
e.Graphics.DrawClosedCurve(myPen, myPointArray);
e.Graphics.FillClosedCurve(mySolidBrush, myPointArray);
GraphicsPath myGraphicsPath = new GraphicsPath();
myPointArray = new Point[]
{
new Point(150, 200),
new Point(200, 400),
new Point(250, 300)
};
FontFamily myFontFamily = new FontFamily("Times New Roman");
PointF myPointF = new PointF(150, 140);
StringFormat myStringFormat = new StringFormat();
myGraphicsPath.AddArc(200, 300, 30, 20, -90, 180);
myGraphicsPath.AddCurve(myPointArray);
myGraphicsPath.AddString("a string in a path", myFontFamily,
0, 50, myPointF, myStringFormat);
myGraphicsPath.AddPie(230, 210, 40, 40, 40, 110);
e.Graphics.FillPath(mySolidBrush, myGraphicsPath);
e.Graphics.DrawPath(myPen, myGraphicsPath);
}
GDI+中的区域Regions
//Region示例
var myRegion1 = new Region(new Rectangle(100, 200, 200, 100));
var graphicsPath = new GraphicsPath();
graphicsPath.AddClosedCurve(new Point[] {
new Point(150,180),
new Point(230,210),
new Point(500,250),
new Point(190,260)
});
var myRegion2 = new Region(graphicsPath);
using (var mySolidBrush1 = new SolidBrush(Color.LightGreen))
using (var mySolidBrush2 = new SolidBrush(Color.LightBlue))
{
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
e.Graphics.FillRegion(mySolidBrush2, myRegion2);
//ExcludeClip示例,画(20,320,300,300的正方形,中间(50,230,200,200)不填充
// Create rectangle for region.
Rectangle excludeRect = new Rectangle(50, 350, 200, 200);
// Create region for exclusion.
Region excludeRegion = new Region(excludeRect);
// Set clipping region to exclude region.
e.Graphics.ExcludeClip(excludeRegion);
// Fill large rectangle to show clipping region.
e.Graphics.FillRectangle(new SolidBrush(Color.Blue), 20, 320, 300, 300);
}
myRegion1.Dispose();
myRegion2.Dispose();
myRegion1.Xor(myRegion2);
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
myRegion1.Intersect(myRegion2);
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
myRegion1.Union(myRegion2);
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
myRegion1.Exclude(myRegion2);
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
myRegion1.Complement(myRegion2);
e.Graphics.FillRegion(mySolidBrush1, myRegion1);
在GDI+中限制绘制图面
var myRectangle = new Rectangle(100, 100, 400, 200);
GraphicsPath path = new GraphicsPath();
path.AddEllipse(myRectangle);
GraphicsPath clipPath = new GraphicsPath();
FontFamily myFontFamily = new FontFamily("Times New Roman");
PointF myPointF = new PointF(100, 180);
StringFormat myStringFormat = new StringFormat();
clipPath.AddString("This is clip Path", myFontFamily, 0, 60, myPointF, myStringFormat);
using (var brush = new PathGradientBrush(path))
using (var pen = new Pen(Color.Red, 1))
{
brush.CenterColor = Color.White;
brush.SurroundColors = new Color[] { Color.Blue };
e.Graphics.DrawEllipse(pen, myRectangle);
e.Graphics.Clip = new Region(clipPath);
e.Graphics.FillEllipse(brush, myRectangle);
}
path.Dispose();
clipPath.Dispose();
用直线和曲线抗锯齿
using (var brush1 = new SolidBrush(Color.AliceBlue))
using (var brush2 = new SolidBrush(Color.Yellow))
using (var brush3 = new SolidBrush(Color.White))
using (var brush4 = new SolidBrush(Color.LightGreen))
using (var pen = new Pen(Color.Red, 20))
{
e.Graphics.FillRectangle(brush1, new Rectangle(100, 100, 150, 400));
e.Graphics.FillRectangle(brush2, new Rectangle(250, 100, 100, 400));
e.Graphics.FillRectangle(brush3, new Rectangle(350, 100, 50, 400));
e.Graphics.FillRectangle(brush4, new Rectangle(400, 100, 120, 400));
e.Graphics.DrawLine(pen, 120, 120, 500, 380);
//抗锯齿
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawLine(pen, 120, 160, 500, 450);
}
上面的线条没有抗锯齿,下面的线条有抗锯齿
https://learn.microsoft.com/zh-cn/dotnet/desktop/winforms/advanced/graphics-and-drawing-in-windows-forms?view=netframeworkdesktop-4.8