【学习笔记】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 类。 使用 MetafileHeaderMetaHeader 类,可以检查存储在图元文件标头中的数据。
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 类提供以下方法来绘制上一列表中的项:DrawLineDrawRectangleDrawEllipseDrawPolygonDrawArcDrawCurve(对于基数样条)和 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 类提供以下方法来填充闭合形状和曲线:FillRectangleFillEllipseFillPieFillPolygonFillClosedCurveFillPathFillRegion

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

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图南堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值