注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

C# Graphics Programming笔记(一)  

2011-10-14 20:47:46|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最近找工作挺麻烦的,只能从海绵里面挤点时间出来看看书,多学点东西,顺便求看到消息的HR能赏个offer,要求不高,钱多事少离家进,要是解决老婆和住房就跟定了。

回到正题上来,这本书依旧是红皮书系列的,由Rod Stephens编写,网上有电子版的,使用搜索引擎一下就能找到,不过只有英文版的,好在对英文水平要求不高,过了CET-4绝对可以无障碍阅读。全书分8个章节,从简单的图形对象、画笔、刷子到复杂的位图、图形变换、打印等技术,最后还描述了一个从WPF而来的强有力的对象:FlowDocument,虽然这本书不能做到面面俱到而又深动详实,但全书言简意赅,结构紧凑,从宏观的角度介绍了GDI+编程的原理和方法,是一本不错的GDI+编程入门书籍。

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~
===========================================================================================
第一章:使用图形、画笔和刷子

Grapgics对象类似画布或者一张纸,供其他对象在上面作图。Pen对象决定了图形中的线型,而Brush则决定区域的属性。

获取Graphics对象有如下方法:

调用窗体或者控件的CreateGraphics方法,该方法返回一个Graphics对象实例。

Graphics gr = this.CreateGraphics();

gr.FillEllipse(Brushes.Yellow, 10, 30, 200, 150);

调用Graphics类的FromImage方法,该方法是一个静态方法。

Bitmap bm = new Bitmap(200, 100);

Graphics gr = Graphics.FromImage(bm);

gr.FillEllipse(Brushes.Pink, 10, 10, 180, 80);

使用Paint事件处理函数的e.Graphics参数

private void Form1_Paint(object sender, PaintEventArgs e)

{

    e.Graphics.Clear(this.BackColor);

    e.Graphics.DrawLine(Pens.Blue, 0, 0,this.ClientSize.Width, this.ClientSize.Height);

    e.Graphics.DrawLine(Pens.Blue,this.ClientSize.Width, 0, 0, this.ClientSize.Height);

}

使用PrintDocument 对象的PrintPage事件处理函数的e.Graphics参数

这个看起来没什么问题:

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

但是当窗体尺寸发生变化的时候:

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~ 

窗体尺寸改变时,Paint 事件重绘窗口,但是Paint 事件处理函数的参数e.Graphics 对象只传递了新的区域,原本可见的区域并不重画。

最简单的方法是这样:

private void Form1_Load(object sender, EventArgs e)

{

    this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw,true);

}

该方法要求了Paint重画所有窗体

PrintDocument对象的PrintPage事件的参数e也提供了Grapgics对象的实例。

使用Graphics对象

该类主要提供绘图、填充和输出文本的功能。方法可查看网页:

http://msdn.microsoft.com/library/system.drawing.graphics_methods.aspx

另外还有比较重要的属性如Clear,CopyFromScreenDispose,尤其是CopyFromScreen能够复制一部分平面区域的图形。而Dispose方法则释放了图形对象所占用的资源。

下面的方法实现了截图:

private void button1_Click(object sender, EventArgs e)

{

    int width = pictureBox1.Width;

    int height = pictureBox1.Height;

    Size s = pictureBox1.Size;

    Bitmap bmp = new Bitmap(width, height);

    Graphics gr = Graphics.FromImage(bmp);

    Point p1 = new Point(100, 100);//源矩形左上角的点

    Point p2 = new Point(0, 0);//目标矩形左上角的点

    gr.CopyFromScreen(p1, p2, s);

    pictureBox1.Image = bmp;

    gr.Dispose();

}

效果如下:

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

 

Graphics对象有三个属性很重要:

InterpolationMode:插补模式确定如何计算两个终结点之间的中间值,该属性可读写,提供的类型是InterpolationMode,可查看

http://msdn.microsoft.com/zh-cn/library/system.drawing.drawing2d.interpolationmode.aspx

TextRenderingHint:获取或设置与此 Graphics 关联的文本的呈现模式,确定文本呈现提示,指定文本是否以 Antialias 形式呈现。

SmoothingMode:平滑模式指定直线、曲线和已填充区域的边缘是否采用平滑处理(又称锯齿消除功能)。 但有一个例外,路径渐变画笔并不遵循平滑模式。 PathGradientBrush 填充的区域以同样的方式呈现(带锯齿边缘),与 SmoothingMode 属性无关。

创建画笔

Pens下有许多静态变量,类似Color下的变量一样,返回了许多宽度为1的画笔:

下面的两个语句效果相同:

Pen p1 = Pens.Blue;

Pen p2 = new Pen(Color.Blue, 1);

DashStyle决定了画笔的线条样式。标准的有SolidDashDashDotDashDotDotDot

private void Form1_Paint(object sender, PaintEventArgs e)

{

    Point[] pts = {

                    new Point(250, 50),

                    new Point(220, 100),

                    new Point(270, 150),

                    new Point(200, 170),

                    new Point(180, 80),

                    new Point(210, 30)

                    };

    using (Pen the_pen = new Pen(Color.Purple, 5))

    {

        the_pen.DashStyle = DashStyle.Dash;

        //need System.Drawing.Drawing2D

        e.Graphics.DrawPolygon(the_pen, pts);

    }

}

绘制的是虚线形式的图形:

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

 

DashCap决定了线帽的样式,可以是Triangle FlatRound等。

DashOffset属性获取或设置直线的起点到短划线图案起始处的距离

StartCapEndCap属性决定了线条的起点和终点的样式。可以是ArrowAnchorDiamondAnchorFlatRoundRoundAnchorSquareSquareAnchorTriangle

创建刷子

和画笔类似,可以使用如下方式创建:

Brush b1 = Brushes.Yellow;

但是不能使用Brush b1 = new Brush(Color.Yellow);

画一个椭圆,并填充:

private void Form1_Paint(object sender, PaintEventArgs e)

{

    e.Graphics.FillEllipse(Brushes.Yellow, 20, 20, 200, 150);

    using (Pen the_pen = new Pen(Color.Blue, 5))

    {

        e.Graphics.DrawEllipse(the_pen, 20, 20, 200, 150);

    }

}

效果如下:

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

SolidBrush为纯色刷子,就像上面看到的那样。HatchBrush是有填充样式的画刷。例如绘制红色的方砖:

private void Form1_Paint(object sender, PaintEventArgs e)

{

    using (HatchBrush br = new HatchBrush(HatchStyle.DiagonalBrick,Color.Red, Color.Pink))

    {

        e.Graphics.FillRectangle(br, 10, 10, 200, 150);

        e.Graphics.DrawRectangle(Pens.Red, 10, 10, 200, 150);

    }

}

效果如下: 

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

TextureBrush是贴图画刷,能够使用图片填充区域。

private void Form1_Paint(object sender, PaintEventArgs e)

{

    using (TextureBrush br = new TextureBrush(Image.FromFile(@"C:\ColorCircle.png")))

    {

        e.Graphics.FillRectangle(br, this.ClientRectangle);

    }

}

效果如下: 

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

默认是从填充图形的左上角开始的,实际上可以使用TranslateTransform属性调整:

private void Form1_Paint(object sender, PaintEventArgs e)

{

    using (TextureBrush br = new TextureBrush(Image.FromFile(@"C:\ColorCircle.png")))

    {

        br.TranslateTransform(16, 16);

        e.Graphics.FillRectangle(br, this.ClientRectangle);

    }

}

效果如下,注意左上角: 

C Graphics Programming笔记(一) - Castor - 趁年轻,多折腾~~

 

  评论这张
 
阅读(9384)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016