【GDI+】GDI+学习及代码总结之------画刷Brush

画刷Brush

GDI+中定义了五种画刷类型,他们都派生于Brush类,他们分别是:

注意:画刷与画笔不同,画刷只是用来填充区域,所以,画刷无宽度、长度可言。

单色画刷SolidBrush

一、构造函数

[cpp]  view plain copy
  1. SolidBrush greenBrush(Color(255,0,255,0)); //在GDI+中颜色值,没有RGB()构造,只能用Color()构造  
二、所使用的填充函数
[cpp]  view plain copy
  1. graphics.FillClosedCurve();//填充闭合曲线  
  2. graphics.FillEllipse();  //填充椭圆  
  3. graphics.FillPath(); //填充路径  
  4. graphics.FillPie();  //填充扇形  
  5. graphics.FillPolygon(); //填充多边形  
  6. graphics.FillRectangle(); //填充矩形  
  7. graphics.FillRectangles(); //填充矩形集  
  8. graphics.FillRegion(); //填充区域  
对于这些区域填充函数的使用,已经在前面讲过了,大家可以参考《GDI+学习及代码总结之------画线、区域填充、写字》这一篇文章

影线画刷HatchBrush

影线画刷,故名思意,就是用前景色与背景色,根据预定好的横线、竖线及斜线组成的图形,影线画刷用HatchBrush定义,其构造函数为:

[cpp]  view plain copy
  1. HatchBrush::HatchBrush(hatchStyle, foreColor, backColor);//hatchstyle是一个枚举类,枚举了53种风格的影线画刷,forColor:前景色 ,backColor:背景色  
大家看hatchStyle定义:

[cpp]  view plain copy
  1. enum HatchStyle{  
  2.   HatchStyleHorizontal = 0,  
  3.   HatchStyleVertical = 1,  
  4.   HatchStyleForwardDiagonal = 2,  
  5.   HatchStyleBackwardDiagonal = 3,  
  6.   HatchStyleCross = 4,  
  7.   HatchStyleDiagonalCross = 5,  
  8.   HatchStyle05Percent = 6,  
  9.   HatchStyle10Percent = 7,  
  10.   HatchStyle20Percent = 8,  
  11.   HatchStyle25Percent = 9,  
  12.   HatchStyle30Percent = 10,  
  13.   HatchStyle40Percent = 11,  
  14.   HatchStyle50Percent = 12,  
  15.   HatchStyle60Percent = 13,  
  16.   HatchStyle70Percent = 14,  
  17.   HatchStyle75Percent = 15,  
  18.   HatchStyle80Percent = 16,  
  19.   HatchStyle90Percent = 17,  
  20.   HatchStyleLightDownwardDiagonal = 18,  
  21.   HatchStyleLightUpwardDiagonal = 19,  
  22.   HatchStyleDarkDownwardDiagonal = 20,  
  23.   HatchStyleDarkUpwardDiagonal = 21,  
  24.   HatchStyleWideDownwardDiagonal = 22,  
  25.   HatchStyleWideUpwardDiagonal = 23,  
  26.   HatchStyleLightVertical = 24,  
  27.   HatchStyleLightHorizontal = 25,  
  28.   HatchStyleNarrowVertical = 26,  
  29.   HatchStyleNarrowHorizontal = 27,  
  30.   HatchStyleDarkVertical = 28,  
  31.   HatchStyleDarkHorizontal = 29,  
  32.   HatchStyleDashedDownwardDiagonal = 30,  
  33.   HatchStyleDashedUpwardDiagonal = 31,  
  34.   HatchStyleDashedHorizontal = 32,  
  35.   HatchStyleDashedVertical = 33,  
  36.   HatchStyleSmallConfetti = 34,  
  37.   HatchStyleLargeConfetti = 35,  
  38.   HatchStyleZigZag = 36,  
  39.   HatchStyleWave = 37,  
  40.   HatchStyleDiagonalBrick = 38,  
  41.   HatchStyleHorizontalBrick = 39,  
  42.   HatchStyleWeave = 40,  
  43.   HatchStylePlaid = 41,  
  44.   HatchStyleDivot = 42,  
  45.   HatchStyleDottedGrid = 43,  
  46.   HatchStyleDottedDiamond = 44,  
  47.   HatchStyleShingle = 45,  
  48.   HatchStyleTrellis = 46,  
  49.   HatchStyleSphere = 47,  
  50.   HatchStyleSmallGrid = 48,  
  51.   HatchStyleSmallCheckerBoard = 49,  
  52.   HatchStyleLargeCheckerBoard = 50,  
  53.   HatchStyleOutlinedDiamond = 51,  
  54.   HatchStyleSolidDiamond = 52,  
  55.   HatchStyleTotal,  
  56.   HatchStyleLargeGrid = HatchStyleCross,  
  57.   HatchStyleMin = HatchStyleHorizontal,  
  58.   HatchStyleMax = HatchStyleTotal - 1  
  59. };  
这个定义有些长,而且让人搞不懂他们分别对应什么图形,让我们看下面的图像,他们从左至右、从上到下排列,序号分别是0-52,(前景色为:红色,背景色为:绿色),CSDN处理的有些失真,大家可以在MSDN上看下这个枚举类,有对应的图形。 微笑

我们简单使用一下影线画刷,用它来填充两个矩形,示例:

[cpp]  view plain copy
  1. Color forColor(255,0,0,0);  
  2. Color bkColor(255,255,0,255);  
  3.   
  4. HatchBrush brush(HatchStyleHorizontal, forColor, bkColor);  
  5. graphics.FillRectangle(&brush, 20, 20, 100, 50);  
  6.   
  7. HatchBrush brush1(HatchStyleVertical, forColor, bkColor);  
  8. graphics.FillRectangle(&brush1, 140, 20, 100, 50);  

影线画刷的单个与整体

从构成上看,影线画刷是小正方形图案的简单重复,单个的正方形图案决定了画刷的整体外观。下图所示为影线画刷的基本构成:


左图所示是影线画刷放大后的基本图案,该图案由前景色和背景色两部分构成。右图,就是由这些个小的基本图案重复而成。上面所枚举的53种图案,都是由它自己的基本图案重复平铺而成。

设置影线画刷的绘制原点

绘制原点,即在什么地方开始绘制,它并不是指相对所要填充的矩形原点的填充位置,而是对基本图案而言的。设置绘制原点的语句为:

[cpp]  view plain copy
  1. Graphics::SetRenderingOrigin(x, y);//X为相对X轴方向的偏移量,Y为相对Y轴方向的偏移量  
如果我们设置这样一条语句,setRenderingOrigin(0,3);会是什么效果呢?看下面讲解;

我们说了,是相对基本图案而言,我们还是3-13的图,

所以,它先从基本图案的纵向偏移3个相素,然后用偏移后的图案开始绘制

示例:(向下偏移4个相素)

[cpp]  view plain copy
  1. HatchBrush hatchBrush(  
  2.                       HatchStyle(52),   
  3.                       Color(255, 255, 0, 0),     // red  
  4.                       Color(255, 0, 255, 255));  // aqua  
  5.   
  6. graphics.FillRectangle(&hatchBrush, 0, 0, 100, 50);//未偏移前  
  7. graphics.SetRenderingOrigin(0,4);  
  8. graphics.FillRectangle(&hatchBrush, 120, 0, 100, 50);//偏移4个相素  

纹理画刷TextureBrush

纹理画刷,与影线画刷类似,也是使用同样的基本图案在水平和垂直方向上按一定的顺序平铺。不同的是,纹理画刷使用的是基本的图像来做基本图案的。

一、构造函数(待完)

[cpp]  view plain copy
  1. TextureBrush(Image* image, Rect& dstRect, ImageAttributes* imageAttributes)   
  2. TextureBrush(Image* image, RectF& dstRect, ImageAttributes* imageAttributes)   
  3. TextureBrush(image, wrapMode)   
  4. TextureBrush(Image* image, WrapMode wrapMode, Rect& dstRect)   
  5. TextureBrush(Image* image, WrapMode wrapMode, RectF& dstRect)   
  6. TextureBrush(Image* image, WrapMode wrapMode, INT dstX, INT dstY, INT dstWidth, INT dstHeight)   
  7. TextureBrush(Image* image, WrapMode wrapMode, REAL dstX, REAL dstY, REAL dstWidth, REAL dstHeight)   
这里不考虑对于ImageAttributes的设置(后面补充),只考虑除第一个外的其它五个构造函数的使用。
参数说明:

image:指定纹理画刷所使用的源图像,但这个图像并不一定是最终用来画图所用的图像,这只是一个源图,dstRect所指定的区域才是最终所使用的绘图单元图案;

dstRect:用于指定图案中用于画刷中的矩形区域。这个区域是从image中裁剪的。注意,它的大小不能超过基本图案的范围,否则,填充不会成功,也会报错。

wrapMode:指定在画刷中如何排列基本图案。

imageAtributes:用于指定基本图案的附加特征参数。

先看下示例:

基本图案:


代码:

[cpp]  view plain copy
  1. RectF rect1(10,10,200,200);  
  2. RectF rect2(210,10,200,200);  
  3. RectF rect3(410,10,200,200);  
  4.   
  5. Image image(L"img.jpg");  
  6.   
  7. TextureBrush tBrush1(&image);  
  8. graphics.FillRectangle(&tBrush1,rect1); //完整图案填充  
  9.   
  10. TextureBrush tBrush2(&image,Rect(10,10,50,50));  
  11. graphics.FillRectangle(&tBrush2,rect2);//从源图截取一部分填充  
  12.   
  13. TextureBrush tBrush3(&image);  
  14. tBrush3.SetTransform(&Matrix(0.5f,0.0f,0.0f,0.5f,0.0f,0.0f));  
  15. graphics.FillRectangle(&tBrush3,rect3);//缩小0。5倍填充  

这里是填充了,效果也出来了,但有个问题,这里可能大家不会发现,因为图像太乱了,我们单独出一个示例,

代码:

[cpp]  view plain copy
  1. Image image(L"img.jpg");  
  2. UINT X=image.GetWidth();  
  3. UINT Y=image.GetHeight();  
  4. RectF rect(20,230,image.GetWidth(),image.GetHeight());  
  5. TextureBrush tBrush(&image);  
  6. graphics.FillRectangle(&tBrush,rect);  

大家有没有看出问题来,我这里构造了一个矩形,矩形的大小与图像的一样,按说,它的填充效果,应该是图片正好将整个框填满,但事实上,原图左边却少了一块,右边却多出一块来,好像是向右移了20个相素似的,如果我们把

[cpp]  view plain copy
  1. RectF rect(20,230,image.GetWidth(),image.GetHeight());  

改成

[cpp]  view plain copy
  1. RectF rect(0,230,image.GetWidth(),image.GetHeight());  
会怎样呢?

看效果图:


到这大家可能就清楚了,画刷是先把图像从原点(0,0)平铺,然后在要显示的位置截取这一块,显示出来,并不是以要显示的区域的原点为平铺原点的!!!!

二、平铺方式

WrapMode枚举了五种平铺方式;

[cpp]  view plain copy
  1. enum WrapMode{  
  2.   WrapModeTile,  //普通平铺  
  3.   WrapModeTileFlipX,  //水平方向翻转并平铺  
  4.   WrapModeTileFlipY,  //垂直方向翻转并平铺  
  5.   WrapModeTileFlipXY,  //在水平和垂直方向都翻转并平铺,它是WrapModeTileFlipX与WrapModeTileFlipY效果的组合  
  6.   WrapModeClamp  //不进行平铺,只在以(0,0)位置为原点显示一张图片  
  7. };  
示例:

[cpp]  view plain copy
  1. Image image(L"img.jpg");  
  2.   
  3. TextureBrush tBrush1(&image,WrapModeClamp);//不进行平铺  
  4. graphics.FillRectangle(&tBrush1,Rect(0,0,170,200));  
  5.   
  6. TextureBrush tBrush2(&image,WrapModeTile);  //平铺  
  7. graphics.FillRectangle(&tBrush2,Rect(220,0,170,200));  
  8.   
  9. TextureBrush tBrush3(&image,WrapModeTileFlipX);  //水平方向翻转并平铺  
  10. graphics.FillRectangle(&tBrush3,Rect(430,0,170,200));  
  11.   
  12. TextureBrush tBrush4(&image,WrapModeTileFlipY);  //垂直方向翻转并平铺  
  13. graphics.FillRectangle(&tBrush4,Rect(640,0,170,200));  
  14.   
  15. TextureBrush tBrush5(&image,WrapModeTileFlipXY); //在水平和垂直方向都翻转并平铺,它是WrapModeTileFlipX与WrapModeTileFlipY效果的组合  
  16. graphics.FillRectangle(&tBrush5,Rect(850,0,170,200));  

三、画刷变换

纹理画刷的变换分为三种:旋转变换(RotateTransform)、缩放变换(ScaleTransform)和平移变换(TranslateTransform)。基本上与画笔的变换差不多,旋转变换,是将基本图案向左或向右旋转N度;缩放变换是将基本图案放大或缩小;平移变换容易让人迷,它是在绘图原点(0,0)向左移动、向右和向上、向下平移后,再进行平铺。

三种旋转方式的参数代码为:

[cpp]  view plain copy
  1. TextureBrush::RotateTransform(angle, order) //旋转变换,angle为度数,order指定向左还是向右转  
  2. TextureBrush::ScaleTransform(sx, sy, order) //缩放变换,sx为水平放大的倍数,1为不变;sy为垂直放大的倍数,同样,1为不变,不能设为0  
  3. TextureBrush::TranslateTransform(dx, dy, order) //平移变换,dx,dy分别指定沿X轴,沿Y轴平移的相素数,order是指向左平移还是向右平移  
示例:

[cpp]  view plain copy
  1. Image img(L"img.jpg");  
  2. TextureBrush tBrush(&img);  
  3. //原图  
  4. tBrush.ResetTransform();  
  5. graphics.FillRectangle(&tBrush,RectF(0,228,img.GetWidth(),img.GetHeight()));  
  6. //相对绘制原点平移,这里相对的是(0,0)点  
  7. tBrush.TranslateTransform(30,0,MatrixOrderPrepend);  
  8. graphics.FillRectangle(&tBrush,RectF(0,10,200,200));  
  9. //旋转  
  10. tBrush.RotateTransform(60,MatrixOrderAppend);//原本是MatrixOrderAppend是向右转,MatrixOrderPrepend是向左转,但这里设置了后并没有用,两个全都向右转了,说明API有问题  
  11. graphics.FillRectangle(&tBrush,RectF(220,10,200,200));  
  12. //放大缩小  
  13. tBrush.ResetTransform();  
  14. tBrush.ScaleTransform(2,1);//水平放大两倍  
  15. graphics.FillRectangle(&tBrush,RectF(430,10,200,200));  

线性渐变画刷(LinearGradientBrush))

一、构造方法

线性渐变画刷有两种构造方式,两点构造和两条直线构造(矩形构造)

[cpp]  view plain copy
  1. LinearGradientBrush(Point& point1, Point& point2, Color& color1, Color& color2) ;  
  2. LinearGradientBrush(PointF& point1, PointF& point2, Color& color1, Color& color2) ;//两点构造  
  3. LinearGradientBrush(Rect& rect, Color& color1, Color& color2, REAL angle, BOOL isAngleScalable) ;  
  4. LinearGradientBrush(RectF& rect, Color& color1, Color& color2, REAL angle, BOOL isAngleScalable) ;  
  5. LinearGradientBrush(Rect& rect, Color& color1, Color& color2, LinearGradientMode mode) ;  
  6. LinearGradientBrush(RectF& rect, Color& color1, Color& color2, LinearGradientMode mode) ;//矩形构造  
前两个是两点构造,后四个是矩形构造,这里分别讲解。

(一)两点构造

使用两个点来定义色彩渐变区域时,只需用直线两个点连接起来即可,所有与这条连线平等的直线就构成渐变区域,这些直线中的任一条在外观上都是相同的,并且,每条直线色彩的变化反映着整个区域的色彩渐变。如图所示,为使用两个点定义的渐变区域的效果图。


1、构造函数:

[cpp]  view plain copy
  1. LinearGradientBrush(Point& point1, Point& point2, Color& color1, Color& color2) ;  
  2. LinearGradientBrush(PointF& point1, PointF& point2, Color& color1, Color& color2) ;  
示例:

[cpp]  view plain copy
  1. LinearGradientBrush lgBrush1(PointF(0,0),PointF(40,0),Color(255,255,0,0),Color(255,0,0,255));//水平渐变  
  2. LinearGradientBrush lgBrush2(PointF(0,0),PointF(40,40),Color(255,0,255,0),Color(255,255,255,0));//斜向渐变  
  3.   
  4. graphics.FillRectangle(&lgBrush1,0,0,200,200);  
  5. graphics.FillRectangle(&lgBrush2,240,0,200,200);  


2、平铺方式

设置平铺方式的函数:

[cpp]  view plain copy
  1. LinearGradientBrush::SetWrapMode(wrapMode);//wrapMode是个枚举类,包括:  
  2. //WrapModeTile,WrapModeTileFlipXWrapModeTileFlipY,WrapModeTileFlipXY,WrapModeClamp  
  3. //WrapModeClamp不能在这里使用。原因见下面的注意讲解  

与TextureBrush类似,TextureBrush类的成员函数SetWrapMode可设置平铺方式,图片可以使用水平翻转、垂直翻转或水平垂直叠加翻转方式在目标区域中平铺显示。其实我们的线性渐变画刷在目标区域中也可以这样控制填充方式。

我们可以把线性渐变画刷定义的区域(两点间的连线区域)看成一个单独的基本图案。对线性渐变画刷的填充方式进行控件,也就相当于在纹理画刷中对基本图案排列方式进行控制,是一样的。

示例:

[cpp]  view plain copy
  1. LinearGradientBrush lgBrush2(PointF(0,0),PointF(40,40),Color(255,0,255,0),Color(255,255,255,0));//斜向渐变  
  2. //普通平铺  
  3. lgBrush2.SetWrapMode(WrapModeTile);//默认  
  4. graphics.FillRectangle(&lgBrush2,RectF(0,0,200,200));  
  5. //水平方向翻转并平铺    
  6. lgBrush2.SetWrapMode(WrapModeTileFlipX);  
  7. graphics.SetRenderingOrigin(210,0);//设置绘画原点,默认是从(0,0)开始  
  8. graphics.FillRectangle(&lgBrush2,RectF(210,0,200,200));  
  9. //垂直方向翻转并平铺    
  10. lgBrush2.SetWrapMode(WrapModeTileFlipY);  
  11. graphics.SetRenderingOrigin(420,0);  
  12. graphics.FillRectangle(&lgBrush2,RectF(420,0,200,200));  
  13. //在水平和垂直方向都翻转并平铺,它是WrapModeTileFlipX与WrapModeTileFlipY效果的组合    
  14. lgBrush2.SetWrapMode(WrapModeTileFlipXY);  
  15. graphics.SetRenderingOrigin(630,0);  
  16. graphics.FillRectangle(&lgBrush2,RectF(630,0,200,200));  

注意:需要强调的是,在纹理画刷中使用的WrapModeClamp图片翻转方式,并不能在线性渐变画刷中使用,主要原因是因为纹理画刷和图片是有固定大小的,而线性渐变画刷没有大小,在绘图平面中也无法独立放置。

(二)矩形构造

线性渐变画刷的渐变区域可以通过两条平行的直线来定义。如图所示为使用平行线定义渐变区域的效果图。


假设如图所示的线条1是红色的,线条2是蓝色的,在线条1与线条2之间的区域就是一个从红色到蓝色的渐变区域。使用这种方式定义渐变区域有一个特点,就是在渐变区域中任一与定义区域的直线相平行的直线的色彩都是由一种色彩构成,单条直线的色彩不存在渐变。

构造函数

[cpp]  view plain copy
  1. LinearGradientBrush(Rect& rect, Color& color1, Color& color2, LinearGradientMode mode)   
  2. LinearGradientBrush(RectF& rect, Color& color1, Color& color2, LinearGradientMode mode)   
  3. LinearGradientBrush(Rect& rect, Color& color1, Color& color2, REAL angle, BOOL isAngleScalable)   
  4. LinearGradientBrush(RectF& rect, Color& color1, Color& color2, REAL angle, BOOL isAngleScalable)   
前两个通过指定矩形的大小的色彩及填充方式来定义画笔。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值