GDI+学习之路


     前些日子做了一个C#项目,里面用到了很多关于C#GDI+方面的知识,也遇到了很多问题。而当我在网上找问题的解决办法的时候,大部分都是在E文网站上找到的,中文的网站关于这方面的知识却很少(也许我太笨了,没找到!)。所以我就想把我的学习GDI+的历程写一下,供大家参考,有不对的地方请大家指正,共同讨论,一起进步!(注:我的所有知识大部分都是翻译E文的网站上的知识,在加上自己的一些见解)。
1. GDI+的基本知识
     GDI+是GDI(Grpahics Device Interface 图形设备接口)的后续版本,提供了高级图象处理的功能。
它主要提供了三类服务:二维矢量图形,图象处理,文字显示。在图形用户界面像Microsoft Windows,在屏幕上绘画是一项非常重要的工作。显示在屏幕的每一样东西都是基于简单的绘画操作。在VS中,当你用GDI+的时候,会很容易的使用它的功能,绘画图表或者是绘画出用户自定义控件或者按钮。GDI+提供了所有的绘画操作,例如:绘画线,曲线,圆,椭圆,位图等,它也能使开发者用颜色,图案或者文理来填充指定的区域。所有的GDI+绘图都是通过Graphics对象绘画的,这个对象提供了大量的在画布上绘画的方法,它也支持大量的绘画画布,包括: 窗口,图象和打印机。根据不同的画布类型可以创建不同的Graphics对象,例如:如果你想修改一个Bitmap图象的内容,你必须用FromImage() 方法创建一个Bitmap画布。
命名空间的说明:
System.Drawing:主要提供对基本图形的访问,有Graphics类,Bitmap类,从Brush类继 承的类,Font类,Icon类,Image类,Pen类和Color类
System.Drawing.Drawing2D:提供了高级二维是矢量图象处理功能
System.Drawing.Imageing提供了高级图象处理功能。
System.Drawing.Text:提供了自己和文字排版功能。
     在WinForms-from 绘画是一件非常奇特的事情,因为它会不止一次的绘画,窗体不停的刷新,也就是重绘。当你改变窗体的大小,或者有别的窗体覆盖了你的窗体,你都会发有重绘事件发生,有的时候是局部重绘。我们在什么地方开始绘画呢?最容易的办法就是窗体或者控件的paint event事件,因为在PaintEvent的参数中,有一个是Graphics obj的句柄。在C#中我们可以通过下面的代码来访问Graphics obj:
     Private void Form1_Paint(object sender,System.Windows.Forms.PaintEventArgs e)
    {
      Graphics g = e.Graphics;
    }
     当然我们也可以通过当前窗体的CreateGraphics方法创建一个G obj如:Graphics g =this.CreateGraphics();或者重继承自图象的任何对象中创建G obj如:Graphics g = Graphics.FromImage(new Bitmap(@”\pic.bmp”)).
2. 绘画简单的图象
     通过Graphics obj 绘画最基本的任务是画直线和曲线。你可以通过一个简单的方法来完成这个目的。但是你必须考虑一系列问题:你需要选择画线的种类,直线还是曲线?你想画一些简单的线,还是一些复杂的线(虚线)?也许你还想在线的开始端和结束端画上某一关闭的形状(如箭头,圆,或者多边行)。依据你的需求可以用不同的方法来实现。当你画线的时候你可以指定一些线的属性:颜色,厚度,开始点坐标和结束点坐标,是否以圆形开始或者以箭头结束。
     在GDI+中,线用钢笔对象来绘画,Pens对象封装了上面的所有的属性。下面的代码示范了用不同Pens来绘画一些简单的直线。
     g.DrawLine(Pens.Red,10,10,200,100)
     g.DrawLine(Pens.Green,10,30,200, 120)
     g.DrawLine(Pens.Blue,10,50,200,140)
     如果你想调整一下线的厚度,你必须实例化一个自定义的Pen对象,代码如下:
     g.DrawLine( New Pen(Color.Red, 5), 10, 100, 200, 190)
     当你用DrawLine()方法的时候,你可能会发现它还大量的重载方法,它们的结果是一样的,只是通过的路径不同,我建议你每个都试一下。
     例如:你可以画园和椭圆:g.DrawEllipse(Pens.Red, 10, 10, 150, 80)
     同样,你可以画一个矩形:g.DrawRectangle(Pens.Green, 20, 100, 120,60)
     你还可以画贝赛儿曲线:g.DrawBezier(Pens.Blue, 170, 10, 250, 90, 170, 90, 250, 180)
     图例效果请自己运行,试看。
3. 绘画复杂的图象
     当你创建用户自定义控件的时候,绘画线和矩形是一个非常好的方法。你想绘画一些更复杂,美感的一些图形,例如图表,GDI+也可以帮你完成这样的功能。它是通过Graphics Path来实现的。
     GraphicsPath 对象封装了一些零散图形的方法。你可以添加一些基本的图形,例如:AddElipse(),AddLine()。GraphicsPath对象能根据它们自动的把图象关联起来,产生一些复杂的图象。例如下面的代码:
     GraphicsPath Person = New GraphicsPath()
     Person.AddEllipse(23, 1, 14, 14)
     Person.AddLine(18, 16, 42, 16)
     Person.AddLine(50, 40, 44, 42)
     Person.AddLine(38, 25, 37, 42)
     Person.AddLine(45, 75, 37, 75)
     Person.AddLine(30, 50, 23, 75)
     Person.AddLine(16, 75, 23, 42)
     Person.AddLine(22, 25, 16, 42)
     Person.AddLine(10, 40, 18, 16)
     g.DrawPath(Pens.Blue, Person)
     你知道上面会产生一个什么形状么?上面简单的代码绘画了一个Person,嘿嘿,是不是很兴奋?
     注意:GraphicsPath 属于System.Drawing.Drawing2D命名空间下的。
4. 绘画图象的质量
     你绘画图形的质量是一个值得讨论的问题。当你绘画一条直线的时候,线的质量并不需要关注,因为GDI+通过不同像素的颜色把它们连接成一行。但是当你绘画一个角度或者曲线的时候,事情似乎变得复杂一点了。在你显示器上显示的像素不是简单的直接相连,而经过一些精确的数学计算,什么样的像素应该显示的,什么样像素点应该丢弃。这个过程被成为颜色混淆处理。颜色混淆导致图象难看,你会发现锯齿,剃度的效果。不过,你可以运用反混淆的技术来解决这个问题,使的图象变的平滑,舒展。下面的代码演示了这个现象和解决办法:
     Pen oPen = New Pen(Color.Blue, 3)
     g.SmoothingMode = SmoothingMode.HighSpeed
     g.DrawBezier(oPen, 10, 10, 90, 90, 10, 90, 90, 180)
     g.SmoothingMode = SmoothingMode.AntiAlias
     g.DrawBezier(oPen, 50, 10, 130, 90, 50, 90, 130, 180)
     g.SmoothingMode = SmoothingMode.HighQuality
     g.DrawBezier(oPen, _90, 10, 170, 90, 90, 90, 170, 180)



     上面是我发表的第一篇文章,有什么不对的地方希望大家批评指正,请大家多多支持。
其余的章节我想总结一些图行的简单操作,web如果使用Graphics,图象的处理,如反色,变色,放大,缩小等一些类似photoshop的功能。
    (转载请尊重版权)

posted @ 2008-04-11 13:24  觉知的凡夫  阅读(842)  评论(0编辑  收藏  举报