C# GDI+绘图 z

技术杂谈53

一、坐标系

坐标系是图形设计的基础。GDI+使用三个坐标空间:世界、页面和设备,其中,世界坐标是用于建立特殊图形世界模型的坐标系,也是在.NET Framework中传递给方法的坐标系。而页面坐标系是指绘图图画(如窗体、控件)使用的坐标系。设备坐标系是在其上绘制的物理设别(如屏幕和纸张)所使用的坐标系。

坐标系总是以左上角为原点(0,0),除了原点之外,坐标系还包括横坐标(X轴)和纵坐标(Y轴)

二、像素

像素全称为图像元素,它是构成图像的基本单位。通常以像素每英寸PPI(pixels per inch)为单位来表示图像分辨率的大小。例如:1024*768分辨率表示水平方向上每英寸长度上的像素数是1024,垂直方向是768

三、绘图

3.1 画笔

画笔使用Pen类表示,主要用于绘制线条,或者线条组合成的其他几何形状,它的构造函数为:

public Pen(Color color, float width)

参数说明:color 设置Pen的颜色

width 设置Pen的宽度

例如创建一个Pen对象,使其颜色为蓝色,宽度为2

Pen MyPen = new Pen(Color.Blue, 2);

以上内容参照自MSDN,详细参考 MSDN Pen Class

3.2 画刷

画刷使用Brush类表示,主要用于填充几何图形,如将正方形和圆形填充其他颜色等。它是一个抽象基类,不能实例化。如果要创建一个画刷对象,需要使用从Brush类派生出的类。

Brush类常用的派生类及说明:

派生类 说明 SolidBrush 定义单色画刷 HatchBrush 提供一种特定样式的图形,用来制作填满整个封闭区间的绘图效果 LinerGradientBrush 提供一种渐变色彩的特效,填充图形的内部区域 TextureBrush 使用图像来填充图形的内部

Brush MyBrush = new SolidBrush(Color.BlueViolet);

HatchBrush hb = new HatchBrush(HatchStyle.DiagonalBrick, Color.Yellow);

LinearGradientBrush linGrBrush = new LinearGradientBrush(
   new Point(0, 10),
   new Point(200, 10),
   Color.FromArgb(255, 255, 0, 0),
   Color.FromArgb(255, 0, 0, 255));

上面代码创建了不同类型的画刷对象,创建后面两个画刷对象是需要引入System.Drawing.Drawing2D命名空间

以上内容来自MSDN,详情参看MSDN Brush Class

3.3 绘制直线

调用Graphics类中的DrawLine方法,结合Pen对象可以绘制直线(如果对Graphics类不了解,可以参考我之前写的博客 C#之Graphics类

DrawLine方法有两种构造函数:

public void DrawLine(Pen pen, Point pt1, Point pt2);

参数说明: pt1 Point结构或PointF结构,表示要连接的第一个点 pt2 表示要连接的第二个点

Point和PointF使用方法完全相同,只是Point的X和Y的类型为int,而PointF的X和Y为float,因此PointF通常用于表示坐标不是整数的情况

public void DrawLine(Pen pen, int x1, int y1, int x2, int y2);
public void DrawLine(Pen pen, float x1, float y1, float x2, float y2);
// x1,y1,x2,y2 分别表示第一个点的横纵坐标和第二个点的横纵坐标

3.4 绘制矩形

通过Graphics类中的DrawRectangle或者FillRectangle方法可以绘制矩形

public void DrawRectangle(Pen pen, float x, float y, float width, float height);
public void DrawRectangle(Pen pen, int x, int y, int width, int height);
//x,y表示要绘制矩形左上角的x坐标和y坐标
//width表示要绘制矩形的宽度,height表示高度
public void FillRectangle(Brush brush, float x, float y, float width, float height);
public void FillRectangle(Brush brush, int x, int y, int width, int height);

DrawRectangle和FillRectangle的区别是DrawRectangle只是绘制图形,FillRectangle是对图形进行填充

*[En]*

**

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace GDI_绘图
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Graphics g = CreateGraphics();
            Pen MyPen = new Pen(Color.Blue, 2);
            int x = 100;
            for (int i = 0; i 10; i++)   //绘制纵向线条
            {
                g.DrawLine(MyPen, x, 400, x, 100);
                x += 40;
            }
            Thread.Sleep(200);  //线程休眠200毫秒,便于观察绘制情况
            int y = 400;
            for (int i = 0; i < +10; i++)   //绘制横向线条
            {
                g.DrawLine(MyPen, 100, y, 550, y);
                y -= 30;
            }
            Thread.Sleep(200);
            x = 110;
            y = 400;
            Brush MyBrush = new SolidBrush(Color.BlueViolet);
            int[] saleNum = { 120, 178, 263, 215, 99, 111, 265, 171, 136, 100, 129 };
            for(int i = 0; i)
            {
                g.FillRectangle(MyBrush, x, y-saleNum[i], 20, saleNum[i]);  //绘制填充矩形
                x += 40;
            }
        }
    }
}

C# GDI+绘图 z

3.5 绘制椭圆

可以使用Graphics类中的DrawEllipse方法或者FillEllipse方法来绘制椭圆,它的语法为:

public void DrawEllipse(Pen pen, RectangleF rect)
public void DrawEllipse(Pen pen, float x, float y, float width, float height)
public void DrawEllipse(Pen pen, Rectangle rect)
public void DrawEllipse(Pen pen, int x, int y, int width, int height)

它与绘制矩形类似,参数中 rect 是Rectangle结构或RectangleF结构,用来定义椭圆的边界

public void FillEllipse(Brush brush, RectangleF rect);
public void FillEllipse(Brush brush, float x, float y, float width, float height);
public void FillEllipse(Brush brush, Rectangle rect);
public void FillEllipse(Brush brush, int x, int y, int width, int height);

3.6 绘制圆弧

通过DrawArc方法,可以绘制圆弧,其语法入下

public void DrawArc(Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle);
public void DrawArc(Pen pen, Rectangle rect, float startAngle, float sweepAngle);
public void DrawArc(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle);
public void DrawArc(Pen pen, RectangleF rect, float startAngle, float sweepAngle);

参数说明:startAngle:从X轴到弧线的起始点沿顺时针方向度量的角(以度为单位)

sweepAngle: 从startAngle参数到弧线的结束点沿顺时针方向度量的角(以度为单位)

其余参数在前面已经讲过了,就不再赘述

3.7 绘制扇形

DrawPie方法和FillPie方法可以绘制扇形,其中DrawPie可以绘制参数指定的扇形,而FillPie则是填充参数指定的扇形,其语法入下
C# GDI+绘图 z

public void FillPie(Brush brush, int x, int y, int width, int height, int startAngle, int sweepAngle);
public void FillPie(Brush brush, Rectangle rect, float startAngle, float sweepAngle);
public void FillPie(Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle);

3.8 绘制多边形

多边形是指由三条或更多边的闭合图形,如三角形、四边形、五边形等。可以使用DrawPolygon方法或者FillPolygon方法绘制多边形,需要使用Graphics对象,Pen对象和Point(或PointF)对象数组,其语法如下

public void DrawPolygon(Pen pen, PointF[] points);
public void DrawPolygon(Pen pen, Point[] points);

public void FillPolygon(Brush brush, PointF[] points);
public void FillPolygon(Brush brush, Point[] points);public void FillPolygon(Brush brush, Point[] points, FillMode fillMode);public void FillPolygon(Brush brush, PointF[] points, FillMode fillMode);

参数中 points为Point或PointF对象数组

fillMode: 确定填充样式的 System.Drawing.Drawing2D.FillMode 枚举的成员。,使用时要引用System.Drawing.Drawing2D命名空间

作为枚举类型,其定义如下

public enum FillMode
    {
        //
        // 摘要:
        //     指定备用填充模式。
        Alternate = 0,
        //
        // 摘要:
        //     指定环绕的填充模式。
        Winding = 1
    }

下面举个绘制三角形的例子

private void button2_Click(object sender, EventArgs e)
        {
            Graphics g = CreateGraphics();
            Pen myPen = new Pen(Color.Green,2);
            Point p1 = new Point(10, 10);
            Point p2 = new Point(10, 90);
            Point p3 = new Point(90, 90);
            Point[] points = new Point[3];
            Brush myBrush = new SolidBrush(Color.Green);
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            g.FillPolygon(myBrush, points,FillMode.Winding);
        }

C# GDI+绘图 z

3.9 绘制图像

可以使用DrawImage方法绘制图像,该方法有多种形式,常用的语法格式为

public void DrawImage(Image image, int x, int y);
public void DrawImage(Image image, int x, int y, int width, int height);

参数说明:img:要绘制的Image

x: 所要绘制图像的左上角的X坐标

y: 所要绘制图像的左上角的y坐标

width:要绘制图像的宽度

height: 要绘制图像的高度

private void button2_Click(object sender, EventArgs e)
        {
            Graphics g = CreateGraphics();
            Image img = Image.FromFile("test.jpg");
            g.DrawImage(img, 50, 20, 90, 20);
        }

四、颜色

4.1 系统定义的颜色

系统定义的颜色使用Color结构的属性来表示,如:

Color myColor = Color.Red;

4.2 自定义颜色

可以使用Color结构的FromArgb方法,分别制定R、G、B颜色值

public static Color FromArgb(int red, int green, int blue);

参数说明:red:新的红色分量值 System.Drawing.Color。 有效值为 0 到 255 之间。

green:新的绿色分量值 System.Drawing.Color。 有效值为 0 到 255 之间。

blue:新的蓝色分量值 System.Drawing.Color。 有效值为 0 到 255 之间。

也可以制定Alpha透明度

public static Color FromArgb(int alpha, int red, int green, int blue);

alpha:Alpha 分量。 有效值为 0 到 255 之间。 黑表示透明,白表示不透明,灰表示半透明

五、文本输出

5.1 字体

字体使用Font类表示,用来定义特定的文本格式,常用的构造函数有:

参数:
        //   family:
        //     新 System.Drawing.Font 的 System.Drawing.FontFamily。
        //
        //   emSize:
        //     新字体的全身大小(以磅为单位)。
        //
        //   style:
        //     新字体的 System.Drawing.FontStyle。
        //
        // 异常:
        //   T:System.ArgumentException:
        //     emSize 是小于或等于 0,计算结果为无穷大,或者不是有效的数字。
        //
        //   T:System.ArgumentNullException:
        //     family 为 null。
        public Font(FontFamily family, float emSize, FontStyle style);

例:

Font myFont = new Font("宋体", 18, FontStyle.Bold);

其中FontStyle使用枚举表示,其成员有:

//
    // 摘要:
    //     指定应用于文本的样式信息。
    [Flags]
    public enum FontStyle
    {
        //
        // 摘要:
        //     普通文本。
        Regular = 0,
        //
        // 摘要:
        //     显示为粗体文本。
        Bold = 1,
        //
        // 摘要:
        //     斜体文本。
        Italic = 2,
        //
        // 摘要:
        //     带下划线的文本。
        Underline = 4,
        //
        // 摘要:
        //     有一条线穿过中部的文本。
        Strikeout = 8
    }

5.2 输出文本

通过DrawString方法,可以指定位置以指定的Brush和Font对象绘制指定的文本字符村,其常用语法格式为:

// 参数:
        //   s:
        //     要绘制的字符串。
        //
        //   font:
        //     System.Drawing.Font,它定义字符串的文本格式。
        //
        //   brush:
        //     System.Drawing.Brush,它确定所绘制文本的颜色和纹理。
        //
        //   x:
        //     所绘制文本的左上角的 x 坐标。
        //
        //   y:
        //     所绘制文本的左上角的 y 坐标。
        //
        // 异常:
        //   T:System.ArgumentNullException:
        //     brush 为 null。 - 或 - s 为 null。
        public void DrawString(string s, Font font, Brush brush, float x, float y);

Original: https://www.cnblogs.com/zeroone/p/10454523.html
Author: 武胜-阿伟
Title: C# GDI+绘图 z



相关阅读

Title: k8s入门教程

1. k8s概述

Kubernetes(简称K8S) 是Google开源的分布式的容器管理平台,方便我们在服务器集群中管理我们容器化应用。

教程主要介绍怎么使用阿里云容器服务(kubernetes版本)。

2. k8s常用概念介绍

  • 节点 (Master node and Worker node)
    节点通常指的就是服务器,在k8s中有两种节点:管理节点(Master Node)和工作节点(Worker Node)
    管理节点(Master Node):负责管理整个k8s集群,一般由3个管理节点组成HA的架构。
    工作节点(Worker Node):主要负责运行容器。

  • 命名空间 (Namespace)
    k8s命名空间主要用于隔离集群资源、隔离容器等,为集群提供了一种虚拟隔离的策略;默认存在3个名字空间,分别是默认命名空间 default、系统命名空间 kube-system 和 kube-public。

  • Object
    k8s 对象(Object)是一种持久化存储并且用于表示集群状态的实体。k8s 对象其实就是k8s自己的配置协议,总之我们可以通过定义一个object让k8s根据object定义执行一些部署任务、监控任务等等。

  • POD
    Pod是 Kubernetes 部署应用或服务的最小的基本单位。一个Pod 封装多个应用容器(也可以只有一个容器)、存储资源、一个独立的网络 IP 以及管理控制容器运行方式的策略选项。

  • 副本集 (Replica Set,RS)
    是一种控制器,负责监控和维护集群中pod的副本(replicas)数,确保pod的副本数是我们期望的样子。

  • 部署 (Deployment)
    表示对k8s集群的一次更新操作,是k8s集群中最常用的Object,主要用于部署应用。支持滚动升级。

  • 服务 (service)
    是对应用的抽象,也是k8s中的基本操作单元,一个服务背后由多个pod支持,服务通过负载均衡策略将请求转发到容器中。

  • Ingress
    是一种网关服务,可以将k8s服务通过http协议暴露到外部。

  • 无状态应用 & 有状态应用

  • 无状态应用指的是应用在容器中运行时候不会在容器中持久化存储数据,应用容器可以随意创建、销毁;如果一个应用有多个容器实例,对于无状态应用,请求转发给任何一个容器实例都可以正确运行。例如:web应用
  • 有状态应用指的是应用在容器中运行时候需要稳定的持久化存储、稳定的网络标识、固定的pod启动和停止次序。例如:mysql数据库

3. k8s架构

C# GDI+绘图 z

通过上图可以看出k8s整体架构主要由左边的master节点和右边的worker组成,master节点负责对整个集群进行管理,右边的电脑表示worker节点负责运行我们部署的容器。

4. 基于k8s的常见web应用部署架构

C# GDI+绘图 z

从上往下看,ingress作为http请求入口接收客户端请求,ingress根据路由规则将请求转发给对应的服务,服务再根据负载均衡策略将请求转发给对应的容器实例,底层基础云服务由所有容器实例共享。

5. 部署应用

下面是通过阿里云容器服务后台以可视化的方式部署应用。

阿里云部署应用连接。

https://help.aliyun.com/document_detail/87784.html?spm=a2c4g.11186623.6.631.6ca67d26RVHzA4

6. 容器之间共享文件存储

在集群环境中,默认情况如果应用在容器A创建了一个文件,容器B无法读取这个文件。

在k8s中提供了持久卷(Persistent Volumes)解决持久化存储问题,持久卷将存储细节和存储数据访问分离,对于用户而言使用同统一的接口访问不同存储系统上的数据。

根据存储方式不同,k8s支持多种持久卷(Persistent Volumes)类型,阿里云也对k8s进行一些扩展支持,目前支持NAS、OSS、云盘三种持久卷类型。

下面是关于阿里云支持的持久卷类型的介绍:

  • NAS - 阿里云高性能分布式文件系统,支持共享存储。
  • OSS - 阿里云对象存储, 也是一个分布式文件系统,支持共享存储。
  • 云盘 - 阿里云云盘,不支持共享存储。

根据上面的介绍我们可以选择NAS或者OSS实现共享文件数据,OSS主要用于图片,视频存储场景可以支持文件直接对外提供访问服务,在容器共享文件数据,我们一般选择NAS, 下面是K8S使用NAS的教程:

https://help.aliyun.com/document_detail/88940.html?spm=a2c4g.11186623.6.680.18656b80CZtc9r

关于云盘,不能多个容器共享,每个POD独占自己的云盘实例,适合用于为部署有状态应用提供持久化存储,例如部署mysql, 将mysql数据保存到云盘中。

!!!提示:无论使用何种持久卷类型,最终都是以挂载的方式,关联到容器中。 对用户来讲,最终看到的就是一个目录。

7. k8s配置管理

如果希望一个镜像(image)更具有通用性,与环境无关,那么应该将环境相关的配置参数从镜像中分离出来。

举个例子:

我们将一个web应用的代码打包到一个镜像中,如果web应用关于数据库的连接地址、帐号、密码也一同打包到镜像中,那么如果我们希望这个镜像换一个数据库配置信息怎么办? 只能重新打包镜像。

k8s为我们提供了两种配置管理的方式:configMap和secret。

他们都是键值对的形式,区别就是secret专门用于管理铭感信息配置,例如:密码。

无论使用那种方式管理配置,最终配置信息都需要注入到容器中。

目前有两种方式将配置信息注入到容器中:环境变量和挂载(mount)数据卷

  • 通过环境变量方式注入容器,容器中的程序只要通过读取环境变量值就可以获取配置信息。
  • 通过挂载数据卷的方式注入,一般都是挂载到某个目录,只要读取这个目录中的数据就可以获取配置信息。

下面是阿里云使用配置的例子:

首先是创建配置项:

C# GDI+绘图 z

接下来是配置注入到容器中,先看通过环境变量注入:

在阿里云后台新建应用或者编辑应用,都会出现下面的窗口

C# GDI+绘图 z

下面是通过挂载的方式注入配置信息:

同样是在新建应用或者编辑应用窗口中,设置数据卷。

C# GDI+绘图 z

阿里云后台操作详细说明连接:

https://help.aliyun.com/document_detail/86769.html?spm=a2c4g.11186623.6.671.667f142e1EUHo4

Original: https://www.cnblogs.com/pangguoming/p/12156161.html
Author: 庞国明
Title: k8s入门教程