基于VC.NET的GDI+编程入门之画刷

发表于:2007-05-25来源:作者:点击数: 标签:编程VC.NETGDI+之画基于
基于线条的、封闭的图形需要画笔来表现,封闭的形状的典型的特点在于它可以用图形、颜色或模式来填充。 画刷是具有颜色,图形或模式的对象,它用来填充图形内部,这种定义也意味着根据不同的目的有不同的画刷。为了满足这一目标,.NET框架在不同的名字空间中
 基于线条的、封闭的图形需要画笔来表现,封闭的形状的典型的特点在于它可以用图形、颜色或模式来填充。

  画刷是具有颜色,图形或模式的对象,它用来填充图形内部,这种定义也意味着根据不同的目的有不同的画刷。为了满足这一目标,.NET框架在不同的名字空间中使用不同的类来支持画刷。所有画刷的基类是Brush类,它定义在System::Drawing名字空间中。

  一、使用画刷

  因为画刷的主要工作是填充封闭的图形,Graphics类为每一中图形都提供了一个填充方法。这些方法是:

  ·FillRectangle: 填充一个矩形或一个正方形;
  ·FillRectangle: 填充一系列的矩形;
  ·FillEllipse: 填充椭圆或圆
  ·FillPolygon: 填充多边形
  ·FillPie: 填充饼图
  ·FillPath:填充图形路径

  为了填写一个图形,调用上述的一个方法,给它传递一个刷子值,然后是图形的位置和尺寸,例如,如果想绘制一个矩形并用一个画刷来填充它,可以使用与下面相似的代码:

clearcase/" target="_blank" >cc66" width="90%" align="center" bgcolor="#dadacf" border="1">
private: System::Void Form1_Paint(System::Object * sender,PaintEventArgs * e)
{
e->Graphics->FillRectangle(SomeBrush, 20, 20, 200, 160);
}

  总共有四种画刷。

  (一)实心画刷

  最简单的画刷就是实心的,这种画刷只提供了一种颜色,习惯于用它来填充一个区域。为了获得实心画刷,可以使用System.Drawing 名字空间中的SolidBrush类。它只有一个构造函数,语法如下:

public: SolidBrush(Color color);

  color参数必须是有效定义的颜色值,这里是一个例子:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
SolidBrush *brushBlue = new SolidBrush(Color::Blue);
e->Graphics->FillRectangle(brushBlue, 20, 20, 200, 160);
}


图一、代码运行效果图

  如果想用不同的颜色填充不同的图形,不必为每一个图形创建一个新的画刷,任何时候,在对一个已经定义的画刷进行重用之前,只需要简单地更改颜色,正式基于这个原因,SolidBrush类提供了颜色属性,例子代码如下:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
SolidBrush *colorizer = new SolidBrush(Color::Lime);
e->Graphics->FillRectangle(colorizer, 10, 10, 120, 120);
colorizer->Color = Color::Salmon;
e->Graphics->FillRectangle(colorizer, 140, 10, 120, 120);

colorizer->Color = Color::Aqua;
e->Graphics->FillRectangle(colorizer, 10, 140, 120, 120);

colorizer->Color = Color::Navy;
e->Graphics->FillRectangle(colorizer, 140, 140, 120, 120);
}


图二、代码运行效果图

  与在图形编程中使用的绝大部分对象一样,画刷消耗计算机的资源,所以,使用过它以后,需要调用 Dispose()方法来释放它使用的资源。例子代码如下:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
SolidBrush *colorizer = new SolidBrush(Color::Lime);
e->Graphics->FillRectangle(colorizer, 10, 10, 120, 120);

colorizer->Color = Color::Salmon;
e->Graphics->FillRectangle(colorizer, 140, 10, 120, 120);

colorizer->Color = Color::Aqua;
e->Graphics->FillRectangle(colorizer, 10, 140, 120, 120);

colorizer->Color = Color::Navy;
e->Graphics->FillRectangle(colorizer, 140, 140, 120, 120);

colorizer.Dispose();
}
 (二)网格画刷

  网格画刷根据已画或已设计的模式来设置它的填充类型。为了支持网格画刷,.NET框架提供了画刷可以使用的各种模式,这些预先设计的模式对应于网格画刷的类型。这意味着在使用网格画刷时,必须在可用的各种类型中选择想要使用的模式,为了使填充区域更生动,还需要说明所使用的颜色。

  为了获取一个网格画刷,可以使用HatchBrush类,它的其中一个构造函数使用以下语法:

public: HatchBrush(HatchStyle style, Color foreColor);

  参数foreColor是用来绘制模式的颜色,style参数是想使用的网格类型,一些可用的类型是:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
using namespace System::Drawing::Drawing2D;
HatchBrush *brushBackDiag = new HatchBrush(HatchStyle::BackwardDiagonal,
Color::FromArgb(0, 0, 255));
HatchBrush *brushCross = new HatchBrush(HatchStyle::Cross,
Color::FromArgb(200, 0, 0));
HatchBrush *brushDarkDown =
new HatchBrush(HatchStyle::DarkDownwardDiagonal, Color::Salmon);
HatchBrush *brushDarkHorz = new HatchBrush(HatchStyle::DarkHorizontal,
Color::Navy);
HatchBrush *brushDarkUpDiag = new HatchBrush(HatchStyle::DarkUpwardDiagonal,
Color::Pink);
HatchBrush *brushVertical = new HatchBrush(HatchStyle::DarkVertical,
Color::FromArgb(255, 0, 255));
HatchBrush *brushDashDnDiag = new HatchBrush(
HatchStyle::DashedDownwardDiagonal, Color::FromArgb(255, 128, 0));
HatchBrush *brushDashHorz = new HatchBrush(HatchStyle::DashedHorizontal,
Color::FromArgb(0, 128, 192));
HatchBrush *brushDashUpDiag = new
HatchBrush(HatchStyle::DashedUpwardDiagonal, Color::Green);
HatchBrush *brushDashVert = new HatchBrush(HatchStyle::DashedVertical,
Color::Firebrick);
HatchBrush *brushDiagBrisk = new HatchBrush(HatchStyle::DiagonalBrick,
Color::Fuchsia);
HatchBrush *brushDiagCross = new HatchBrush(HatchStyle::DiagonalCross,
Color::Moccasin);
HatchBrush *brushDivot = new HatchBrush(HatchStyle::Divot,
Color::Goldenrod);
HatchBrush *brushDotDiamond = new HatchBrush(HatchStyle::DottedDiamond,
Color::Gainsboro);
HatchBrush *brushDottedGrid = new HatchBrush(HatchStyle::DottedGrid,
Color::Khaki);
HatchBrush *brushForDiag = new HatchBrush(HatchStyle::ForwardDiagonal,
Color::Maroon);
HatchBrush *brushHorz = new HatchBrush(HatchStyle::Horizontal,
Color::Red);
HatchBrush *brushHorzBrick = new HatchBrush(HatchStyle::HorizontalBrick,
Color::SaddleBrown);
HatchBrush *brushLgChkBoard = new HatchBrush(HatchStyle::LargeCheckerBoard,
Color::RoyalBlue);
HatchBrush *brushLgConfetti = new HatchBrush(HatchStyle::LargeConfetti,
Color::MistyRose);
HatchBrush *brushLgGrid = new HatchBrush(HatchStyle::LargeGrid,
Color::Purple);
HatchBrush *brushLtDnDiag = new HatchBrush(
HatchStyle::LightDownwardDiagonal, Color::DarkCyan);
HatchBrush *brushLtHorz = new HatchBrush(HatchStyle::LightHorizontal,
Color::PowderBlue);
HatchBrush *brushUpDiag = new HatchBrush(
HatchStyle::LightUpwardDiagonal, Color::SeaGreen);
HatchBrush *brushLtVert = new HatchBrush(HatchStyle::LightVertical,
Color::Olive);
e->Graphics->FillRectangle(brushBackDiag, 20, 20, 80, 60);
e->Graphics->FillRectangle(brushCross, 120, 20, 80, 60);
e->Graphics->FillRectangle(brushDarkDown, 220, 20, 80, 60);
e->Graphics->FillRectangle(brushDarkHorz, 320, 20, 80, 60);
e->Graphics->FillRectangle(brushDarkUpDiag, 420, 20, 80, 60);

e->Graphics->FillRectangle(brushVertical, 20, 100, 80, 60);
e->Graphics->FillRectangle(brushDashDnDiag, 120, 100, 80, 60);
e->Graphics->FillRectangle(brushDashHorz, 220, 100, 80, 60);
e->Graphics->FillRectangle(brushDashUpDiag, 320, 100, 80, 60);
e->Graphics->FillRectangle(brushDashVert, 420, 100, 80, 60);

e->Graphics->FillRectangle(brushDashVert, 20, 180, 80, 60);
e->Graphics->FillRectangle(brushDiagBrisk, 120, 180, 80, 60);
e->Graphics->FillRectangle(brushDiagCross, 220, 180, 80, 60);
e->Graphics->FillRectangle(brushDivot, 320, 180, 80, 60);
e->Graphics->FillRectangle(brushDotDiamond, 420, 180, 80, 60);

e->Graphics->FillRectangle(brushDottedGrid, 20, 260, 80, 60);
e->Graphics->FillRectangle(brushForDiag, 120, 260, 80, 60);
e->Graphics->FillRectangle(brushHorz, 220, 260, 80, 60);
e->Graphics->FillRectangle(brushHorzBrick, 320, 260, 80, 60);
e->Graphics->FillRectangle(brushLgChkBoard, 420, 260, 80, 60);

e->Graphics->FillRectangle(brushLgGrid, 20, 340, 80, 60);
e->Graphics->FillRectangle(brushLtDnDiag, 120, 340, 80, 60);
e->Graphics->FillRectangle(brushLtHorz, 220, 340, 80, 60);
e->Graphics->FillRectangle(brushUpDiag, 320, 340, 80, 60);
e->Graphics->FillRectangle(brushLtVert, 420, 340, 80, 60);
}


图三、各种网络格画刷效果图

  如果使用上面的构造函数来填充一个图形,选择的模式将绘制在黑色背景上,如果想使用不同的背景,使用下面的构造函数来初始化画刷。

public: HatchBrush(HatchStyle hatchstyle, Color foreColor, Color backColor);

  参数backColor是将用于背景的颜色。

  任何时候,为了得到绘制模式的颜色,可以操作画刷的ForegroundColor属性;为了了解背景颜色,可以操作画刷的BackgroundColor属性;为了知道当前画刷的类型,可以操作它的HatchStyle类型。
 (三)纹理画刷

  网格画刷依赖于已经预先设计的模式来填充图形,在某些情况下,需要设计自己的图案来填充一个图形。要这么做,必须执行两个步骤,首先设计一个图形并存储为一个文件,然后创建一个纹理画刷,并将图案传递给它。

  纹理画刷拥有图案,并且通常使用它来填充封闭的图形。为了对它初始化,可以使用一个已经存在的别人设计好了的图案,或使用常用的设计程序设计的自己的图案,同时应该使图案存储为常用图形文件格式,如BMP格式。这里有一个设计好的位图,被存储为Papers.bmp文件。


图四、位图效果图

  有了图案,这时候就可以使用TextureBrush类,它有多种构造函数,最简单的构造函数只有一个Image对象做为参数,这个构造函数的语法是:

public: TextureBrush(Image *bitmap);

  这个构造函数使用位图作为参数。初始化画刷后,你可以使用它来填充封闭的图形。例如你可以调用Fill...方法。下面是例子:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers);
e->Graphics->FillRectangle(brushPapers, 5, 5, 430, 280);
}


图五、代码运行效果图

  如果使用这个构造函数,编译器自身将对图案的尺寸和位置进行定位,尽管位置必须在(0,0)处,但长和宽必须小于或等于设计的图形尺寸,例如,有一个图案是48x48像素,你使用的图形的宽度和高度必须小于等于48,这样就允许只使用图形的一部分,为此需要使用下面的构造函数:

public: TextureBrush(Image *bitmap, Rectangle destination);

  这个函数的第二个参数规定了图案的尺寸,如果愿意使用十进制的矩形参数,可以使用如下构造函数:

public: TextureBrush(Image *bitmap, RectangleF destination);

  这有一个例子:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers,
new Rectangle(0, 0, 40, 42));
e->Graphics->FillRectangle(brushPapers, 5, 5, 438, 290);
}


图六、代码运行效果图

  目前为止我们使用的构造函数都是以平铺的方式在每个定位的矩形内绘制图案。为了更有趣,TextureBrush类提供了一个参数用来指定覆盖模式,可以使用下面的构造函数,

public: TextureBrush(Image *bitmap, WrapMode wrapMode);
public: TextureBrush(Image *bitmap, WrapMode wrapMode, Rectangle destination);
public: TextureBrush(Image *bitmap, WrapMode wrapMode, RectangleF destination);

  位图和尺寸参数与上述含义一样,wrapMode参数是枚举WrapMode的一个成员,枚举WrapMode定义在System::Drawing::Drawing2D名字空间中。

  它有下面的成员:

  ·Clamp:在分配的矩形内只绘制一个图案。

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers, WrapMode::Clamp);
e->Graphics->FillRectangle(brushPapers, 5, 5, 438, 290);
}


图七、Clamp方式效果图

  ·Tile:以平铺方式绘图

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers,
WrapMode::Tile, Rectangle(0, 0, 40, 42));
e->Graphics->FillRectangle(brushPapers, 5, 5, 438, 290);
}


图八、Tile方式效果图

  ·TileFlipX:水平方向交差对称方式

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers, WrapMode::TileFlipX);
e->Graphics->FillRectangle(brushPapers, 5, 5, 430, 290);
}


图九、TileFlipX方式效果图

  ·TileFlipXY:水平竖直方向均交叉对称

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Bitmap *bmpPapers = new Bitmap(S"Papers.bmp");
TextureBrush *brushPapers = new TextureBrush(bmpPapers,
WrapMode.TileFlipXY, Rectangle(0, 0, 42, 42));
e->Graphics->FillRectangle(brushPapers, 5, 5, 412, 244);
}


图十、TileFlipXY方式效果图
 (四)渐变画刷

  渐变画刷类似与实心画刷,因为它也是基于颜色的,与实心画刷不同的是,渐变画刷使用两种颜色,它的主要特点是,在使用过程中,一种颜色在一端,而另外一种颜色在另一端。在中间,两种颜色融合产生过渡或衰减的效果。

  渐变画刷有两种:线性画刷和路径画刷

  1、线性渐变画刷
 
  线性渐变画刷在封闭的区域内的两端使用两种颜色,如左端和右端。

  为了支持线性渐变画刷,.NET框架在名字空间System::Drawing::Drawing2D 中对LinearGradientBrush类进行了定义,为了规定填充图形的起点和终点,可以使用下面的构造函数:

public: LinearGradientBrush(Point point1, Point point2, Color color1, Color color2);
public: LinearGradientBrush(PointF point1, PointF point2, Color color1, Color color2);

  第一个参数point1是绘制的起点,第三个参数color1是对应该点的颜色,第二个参数point2对应着绘制的终点,color2是该点的颜色。例子代码如下:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
using namespace System::Drawing::Drawing2D;
LinearGradientBrush *lgb = new LinearGradientBrush(Point(20, 20),
Point(450,20), Color::DarkGreen, Color::LightBlue);
e->Graphics->FillRectangle(lgb, 20, 20, 430, 180);
}


图十一、线性渐变画刷效果

  默认情况下,渐变画刷按照水平渐变的方式填充图形,如果想让颜色按照不同的方向渐变,如垂直或对角线方向,可以使用下面的构造函数:

public: LinearGradientBrush(Rectangle rect, Color color1, Color color2,
LinearGradientMode factor);
public: LinearGradientBrush(RectangleF rect, Color color1, Color color2,
LinearGradientMode factor);

  第一个参数rect是所要填充颜色的矩形,第二个参数是起点的颜色,第三个参数是终点的颜色,第四个参数factor用来决定颜色融合的方向。它可以取以下值:

  Vertical:垂直方向渐变:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
using namespace System::Drawing::Drawing2D;
Rectangle rect(10, 10, 470, 300);
LinearGradientBrush *lgb = new LinearGradientBrush(rect,
Color::DarkRed,Color::White, LinearGradientMode::Vertical);
e->Graphics->FillRectangle(lgb, 10, 10, 450, 280);
}


图十二、代码运行效果图

  Horizontal:水平渐变; BackwardDiagonal:反向对角线渐变; ForwardDiagonal:正向对角线渐变。

  用来指定渐变方向的构造函数有局限性,它只有四个选项,如果需要,可以使用下面的构造函数来指定任意角度的渐变。

public: LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle);
public: LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle);

  第一个参数rect指的是所要画颜色的区域,最后一个参数angle(按顺时针方向计算),定义了颜色融合的方向。参数color1是开始点的颜色,参数color2是终点的颜色。这里有个例子:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
using namespace System::Drawing::Drawing2D;
Rectangle rect(10, 10, 470, 300);
LinearGradientBrush *lgb = new LinearGradientBrush(rect,
Color::DarkRed, Color::White, -65.24F);
e->Graphics->FillRectangle(lgb, 10, 10, 450, 280);
}


图十三、代码运行效果图

  2、路径渐变画刷

  第二种可用的渐变画刷就是路径渐变画刷,这种画刷用在路径上,来产生渐变效果。.NET 框架在System.Drawing.Drawing2D名字空间中提供了 PathGradientBrush,这个类比有两个构造函数:

public: PathGradientBrush(Point points[]);
public: PathGradientBrush(PointF points[]);

  传递给这个构造函数的参数是Point类型的数组,这里有一个例子:

private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
using namespace System::Drawing::Drawing2D;
Point ptGraph[] = { Point(10, 10),
Point(450, 10),
Point(450, 250),
Point(10, 250) };
PathGradientBrush *pgb = new PathGradientBrush(ptGraph);
e->Graphics->FillRectangle(pgb, 10, 10, 450, 280);
}


图十四、代码运行效果图

原文转自:http://www.ltesting.net

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)