【GDI+编程】--汇总+实战



        上篇博客说了些题外话,为什么偏偏在这时候讨论事件和委托。对于事件和委托是.NET程序猿必须掌握的一堂课,是程序猿踏入设计而不是编写的里程碑,了解了事件的形成就能够使用代码编写动态创建的事件,而学会了委托才能真正的踏入设计的阶段。

       好了回到我们文章的正题,从番外篇回来要开始我们GDI+的旅程啦,今天我们对GDI+的基本架构屡屡,并利用GDI+的几个基本的类来绘制一个圆柱形,重点在于通过实例来区分Graphics和GraphicsPath两个类之间的关系。

       GDI+常用类的划分,通过下图你还不能了解GDI+的奥秘,好戏在后头……

【GDI+编程】--汇总+实战_第1张图片

一、汇总


 先说图形


       也许你要问为什么会有Graphics和GraphicsPath两种类的划分,是啊为什么呢?要从根本上区分两者,首先要看它们的作用,Graphics是在System.Drawing命名空间下的一个类,主要用于图形界面的显示,另外也封装了多种图形的绘制方法,而且还包括了图形的剪辑。
 
       接着来看GraphicsPath类,该类和Graphics类最大的区别是两者分属的命名空间不同,GraphicsPath类是System.Drawing.Drawing2D命名空间下的类,提供了一系列相互连接的直线和曲线,它在绘图功能比Graphics类更优,而且灵活。
       Note:图形剪辑功能是使用Graphics类SetClip方法实现的,而GraphicsPath类只封装了基本图形的绘制,它没有提供显示和剪辑的方法。


 再看颜色和图像

        为什么会有两种Brush类和SolidBrush类颜色类?因为SolidBrush是Brush类的一个子类,Brush是一个抽象类,所以在具体的方法中使用时只能通过实例化SolidBrush类来实现颜色的填充。
      相同Bitmap和image也是一种父子关系,Bitmap继承了抽象的父类image,为用户提供了处理由像素数据定义的图像。
      Note:在编程时,我们往往把需要把绘制的图像保存在一个Bitmap对象中,使图像保持不变。                                                                                   
 

  最后区域


       这里为什么要说区域类,它并不属于图形绘制类,是的它指定了一个路径区域,使得我们可以对区域进行操作,灵活的使用该类可以在原图中获取我们想要的区域,另外也提供了区域的放大和缩放等功能。
       Note:它和Graphics和GraphicsPath类一起使用可以获得想要的区域。                                                                                                                               
 
      上面把常用的GDI+编程中使用的类分类汇总了下, 但有些类没有涉及到,如 Rectangle 和 Point 等类可封装 GDI+ 基元, Pen 类用于绘制直线和曲线。
      Note:为什么说Pen类绘制直线和曲线而不是Graphics和GraphicsPath中的方法?因为,在方法中指定了具体绘画的过程,真正实现绘画的是Pen类,它指定了绘制线的样式。


二、实战


        上面我们总结了几种类,接下来做一个实例,使用GDI+绘制一个圆柱形,在实战中深入体会几种类的使用方法。

        绘制思路:首先使用GraphicsPath类来绘制一个闭合的图形,然后绘制圆柱的上底和下底的椭圆。

        清单一:绘制圆柱的闭合区域,使用GraphicsPath类绘制闭合区域,并使用CloseFigure方法闭合该区域,最后使用Graphics类来填充显示该区域。

【GDI+编程】--汇总+实战_第2张图片

private void DrawClosedFigure(PaintEventArgs e)
{
    Graphics g = e.Graphics;
            
    GraphicsPath gp = new GraphicsPath();
    Point p = new Point(20, 20);    //矩形所在的正方形的起始点坐标
    Size s = new Size(540, 380);    //圆柱所在的正方形的大小

    float flaHeight = (float)s.Width / (float)6.75;         //获取上方椭圆的高
    float flaRecHeight = (float)s.Height / (float)2.62;     //获取上方椭圆所在矩形的高的一半
    int intHeight = Convert.ToInt16(Math.Round(flaHeight, 0));
    int intRecHeight = Convert.ToInt16(Math.Round(flaRecHeight, 0));

    Rectangle rect = new Rectangle(p, s);                   //创建一个矩形区域,用来绘制圆柱
    gp.AddArc(rect.X, rect.Y + intHeight, s.Width, intRecHeight, 180, 180); //绘制圆柱形的上半圆
    gp.AddArc(rect.X, rect.Y + rect.Height, s.Width, intRecHeight, 0, 180); //绘制圆柱形的下半圆
    gp.CloseFigure();   //闭合该区域                                             
    g.SmoothingMode = SmoothingMode.HighQuality;    //设置边框圆滑
    g.DrawPath(new Pen(Color.FromArgb(213, 204, 186), 6), gp);     //在绘画板上绘制该画板区域,绘制出想要的边界
    g.FillPath(new SolidBrush(Color.FromArgb(245, 237, 229)), gp);  //填充画板区域的内部
}

      清单二:绘制圆柱形的上底和下底的椭圆,这里绘制的上底没有填充,并且不是闭合的椭圆,这样看起来更形象。

                                                    【GDI+编程】--汇总+实战_第3张图片

private void DrawBottom(PaintEventArgs e)
{
    Graphics g = e.Graphics;

    Point p = new Point(20, 20);    //矩形所在的正方形的起始点坐标
    Size s = new Size(540, 380);    //圆柱所在的正方形的大小

    float flaHeight = (float)s.Width / (float)6.75;         //获取上方椭圆的高
    float flaRecHeight = (float)s.Height / (float)2.62;     //获取上方椭圆所在矩形的高的一半
    int intHeight = Convert.ToInt16(Math.Round(flaHeight, 0));
    int intRecHeight = Convert.ToInt16(Math.Round(flaRecHeight, 0));

    Rectangle rect = new Rectangle(p, s);                   //创建一个矩形区域,用来绘制圆柱

    g.FillEllipse(new SolidBrush(Color.FromArgb(213, 204, 186)), rect.X - 2, rect.Y + rect.Height, s.Width + 3, intRecHeight);      //绘制圆柱形的底
    g.DrawArc(new Pen(Color.FromArgb(213, 204, 186), 3), new Rectangle(rect.X, rect.Y + intHeight, s.Width, intRecHeight), 170, 10);    //绘制圆柱形上底出来的左边
    g.DrawArc(new Pen(Color.FromArgb(213, 204, 186), 3), new Rectangle(rect.X, rect.Y + intHeight, s.Width, intRecHeight), 0, 10);      //绘制圆柱形上底出来的右边     
}
          上面的绘制方法最重要的部分没有说明,是关于圆柱的高和底的椭圆比的问题,这个比值相当重要,有了这个比值绘制出来的椭圆才美观……


三、结语

         上文中从GDI+的基础出发,汇总了GDI+编程过程中常用的几种类,通过分类能够使我们更加清晰的分清几种类的用法,能达到灵活的使用几种类来创建图形。另外还有多实践,在实战中深刻的体会它们之间的用法,这样才能做到游刃有余。

你可能感兴趣的:(【GDI+编程】--汇总+实战)