当前位置: 首页 > news >正文

【学习笔记】Windows GDI绘图(一)图形概述、直线、曲线和图形

图形概述

图形概述

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 轴指向下。 默认坐标系统中的度量单位是像素。
GDI+默认坐标系
计算机显示器在称为图像元素或像素的矩形点阵列上创建显示。
像素矩阵
从点(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),   // 顶点1new PointF(50, 500),   // 顶点2new 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);

Region.Xor

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

相关文章:

  • Mysql与Navicat可视化命令大全 ----项目实战
  • java String的Split方法, 分割字符时,保留最后的空字符串
  • VLAN---虚拟局域网
  • 58同城如何降低 80%的机器成本 | OceanBase案例
  • Sping源码(七)—ConfigurationClassPostProcessor —— 后续处理
  • 《QT实用小工具·六十四》QT实现仿Windows消息通知控件可交互
  • 关于Mysql基本概念的理解
  • HCIP-Datacom-ARST自选题库__MPLS简答【4道题】
  • Spark累加器
  • Java设计模式-观察者模式(19)
  • 用户态网络缓冲区设计
  • JavaEE技术之分布式事务(理论、解决方案、Seata解决分布式事务问题、Seata之原理简介、断点查看数据库表数据变化)
  • 51汇编--AD和DA
  • 淄博公司商标驳回复审条件及流程
  • WPS PPT学习笔记 1 排版4原则等基本技巧整理
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Apache Pulsar 2.1 重磅发布
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • Debian下无root权限使用Python访问Oracle
  • jquery cookie
  • k8s如何管理Pod
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • oschina
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 当SetTimeout遇到了字符串
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 7行Python代码的人脸识别
  • MyCAT水平分库
  • ​卜东波研究员:高观点下的少儿计算思维
  • # linux 中使用 visudo 命令,怎么保存退出?
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (2.2w字)前端单元测试之Jest详解篇
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)为什么要选择C++
  • (转)Oracle存储过程编写经验和优化措施
  • (转)编辑寄语:因为爱心,所以美丽
  • ***测试-HTTP方法
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET 4.0中的泛型协变和反变
  • .NET delegate 委托 、 Event 事件
  • .NET 设计模式初探
  • .net 受管制代码
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @Autowired和@Resource装配
  • @javax.ws.rs Webservice注解
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?