![]() |
Texture and Gradient Brushes |
|
Texture Brushes |
|
Introduction |
|
The hatch brushes we have used are based on already designed patterns to fill a shape. In some cases, you may want to create or design your own pattern and use it to fill an area. To do this, you must perform two main steps. First, you must design a picture and save it as a file. Then you must create an object referred to as a texture brush and pass the picture to it. A texture brush is an object that holds a picture and uses it to regularly fill the interior of a closed shape. To initialize it, you can use an existing picture designed by someone else or you can design your own picture using any normal graphics application, including Microsoft Paint that is automatically installed with Microsoft Window. You should have the picture as a file with a normal graphics file extension, which could be .bmp. Here is an example of a designed bitmap saved as Papers.bmp: |
![]() Equipped with the picture, you can then use the TextureBrush class that provides various constructors.
The simplest constructor of this class takes as argument an Image object. The syntax of this constructor is: public TextureBrush(Image bitmap); This constructor expects a bitmap as argument. After initializing the brush, you can use it to fill the interior of a closed shape. For example, you can call a Fill... method to paint its shape. Here is an example: using System;
using System.Drawing;
using System.Windows.Forms;
public class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
Paint += new PaintEventHandler(Exercise_Paint);
}
private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers);
e.Graphics.FillRectangle(brushPapers, 5, 5, 430, 280);
}
}
public class Program
{
public static int Main()
{
Application.Run(new Exercise());
return 0;
}
}
If you use this constructor, the compiler would itself find out the location and dimensions of the picture in the area where it was designed. Although the location must be at (0, 0), the width and the height must be lower or equal to the intended dimensions of the bitmap. For example, if you have a picture that is 48x48 pixels, the width you can use from this picture must be <= 48 and the height must be <= 48. This allows you to use only a portion of the picture if you want. To use a portion of the picture, you can use the following constructor: public TextureBrush(Image bitmap, Rectangle destination); The second argument to this constructor is used to specify the width and height of the picture. If you prefer to use a rectangle whose arguments are decimal numbers, you can use the following constructor: public TextureBrush(Image bitmap, RectangleF destination); Here is an example: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
new Rectangle(0, 0, 42, 42));
e.Graphics.FillRectangle(brushPapers, 5, 5, 416, 290);
}
The constructors we have used so far allow you to draw the bitmap in each allocated rectangle in a tiled fashion. To make it more fun, the TextureBrush class is equipped with a factor referred to as wrap mode. This factor specifies how the tiling must be performed. To apply it, you can use one of the following constructors: public TextureBrush(Image bitmap, WrapMode wrapMode); public TextureBrush(Image bitmap, WrapMode wrapMode, Rectangle destination); public TextureBrush(Image bitmap, WrapMode wrapMode, RectangleF destination); The bitmap and the destination arguments are used in the same way we have done so far. The wrapMode argument is a member of the WrapMode enumerator. The WrapMode enumerator is defined in the System.Drawing.Drawing2D namespace. It has the following members: Clamp: Draws one picture in the allocated rectangle: using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
public class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
Paint += new PaintEventHandler(Exercise_Paint);
}
private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
WrapMode.Clamp);
e.Graphics.FillRectangle(brushPapers, 5, 5, 438, 290);
}
}
public class Program
{
public static int Main()
{
Application.Run(new Exercise());
return 0;
}
}
Tile: Draws the picture continuous in a tiled fashion: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
WrapMode.Tile,
new Rectangle(0, 0, 42, 42));
e.Graphics.FillRectangle(brushPapers, 5, 5, 414, 290);
}
TileFlipX: Draws the picture, draws it again on its right side but flipped horizontally, and then repeats this technique continuous in a tiled fashion and in the allocated rectangle: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
WrapMode.TileFlipX);
e.Graphics.FillRectangle(brushPapers, 5, 5, 430, 280);
}
TileFlipY: Draws the picture, draws it again under it but flipped vertically, and then repeats this technique continuous in a tiled fashion and in the allocated rectangle: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
WrapMode.TileFlipX,
new Rectangle(0, 0, 42, 42));
e.Graphics.FillRectangle(brushPapers, 5, 5, 412, 290);
}
TileFlipXY: Draws the picture, draws it again on its right side but flipped horizontally, then draws both the original and the right copy under each other but flipped vertically. These four pictures are redrawn in a tiled fashion and in the allocated rectangle: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Bitmap bmpPapers = new Bitmap("Papers.bmp");
TextureBrush brushPapers = new TextureBrush(bmpPapers,
WrapMode.TileFlipXY,
new Rectangle(0, 0, 42, 42));
e.Graphics.FillRectangle(brushPapers, 5, 5, 412, 244);
}
A gradient brush resembles a solid brush in that it is color-based. Unlike a solid brush, a gradient brush uses two colors. Its main characteristic is that, when used, one color is applied on one side and the other color is applied to the other side. In between, both colors merge to create a transition or fading effect. There are two types of gradient brushes: linear and path.
A linear gradient is used to apply two colors in a closed shape but from one side of the shape, such as the left, to the other opposite side of the shape, such as the right. To support linear gradient brushes, the .NET Framework provides the LinearGradientBrush class defined in the System.Drawing.Drawing2D namespace. To specify the starting and the end points inside of the shape that you want to fill, you can use one of the following constructors: public LinearGradientBrush(Point point1, Point point2, Color color1, Color color2); public LinearGradientBrush(PointF point1, PointF point2, Color color1, Color color2); The first argument, point1, is the point where the drawing would start. The third argument, color1, is the color that would be applied from that point. The second argument, point2, is the point where the drawing would end by applying the color specified by the fourth argument, color2. Here is an example: using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
public class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
Paint += new PaintEventHandler(Exercise_Paint);
}
private void Exercise_Paint(object sender, PaintEventArgs e)
{
LinearGradientBrush lgb =
new LinearGradientBrush(new Point(20, 20),
new Point(450, 20),
Color.DarkGreen,
Color.LightBlue);
e.Graphics.FillRectangle(lgb, 20, 20, 430, 180);
}
}
public class Program
{
public static int Main()
{
Application.Run(new Exercise());
return 0;
}
}
By default, the linear gradient brush fills its gradient based on a horizontal line. If you want the color merge to use a different orientation, such as vertical or diagonal, you can use one of the following constructors: public LinearGradientBrush(Rectangle rect, Color color1, Color color2, LinearGradientMode factor); public LinearGradientBrush(RectangleF rect, Color color1, Color color2, LinearGradientMode factor); The first argument, rect, is the rectangle inside of which the colors would be applied. The second argument, color1, is the color that would be applied from a starting point. The second argument, color2, is the color that would be applied at the other end. The factor argument is used to determine the orientation of the merging colors. It has the following members: Vertical: The first color, color1, is applied to the top section of the rect argument. The second color, color2, is applied to the bottom section of the rect argument: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Rectangle rect = new Rectangle(10, 10, 470, 300);
LinearGradientBrush lgb =
new LinearGradientBrush(rect,
Color.DarkRed,
Color.White,
LinearGradientMode.Vertical);
e.Graphics.FillRectangle(lgb, 10, 10, 450, 280);
}
Horizontal: The first color, color1, is applied to the left section of the rect argument. The second color, color2, is applied to the right section of the rect argument BackwardDiagonal: The first color, color1, is applied to the top-right corner of the rect argument. The second color, color2, is applied to the bottom-left corner of the rect argument: ![]() ForwardDiagonal: The first color, color1, is applied to the top-left corner of the rect argument. The second color, color2, is applied to the bottom-right corner of the rect argument: ![]() The constructor used to produce the above orientation has the limitation that it provides only four options. If you want, you can apply any angular merge as you see fit. To do this, you can use one of the following constructors: public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle); public LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle); The first argument, rect, is the rectangle inside of which the colors would be applied. The last argument, angle, is an angle measured clockwise, that will specify the orientation of the merging colors The second argument, color1, is the color that would be applied from the starting point. The second argument, color2, is the color that would be applied at the other end. Here is an example: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Rectangle rect = new Rectangle(10, 10, 470, 300);
LinearGradientBrush lgb = new LinearGradientBrush(rect,
Color.DarkRed,
Color.White,
-65.24F);
e.Graphics.FillRectangle(lgb, 10, 10, 450, 280);
}
The second type of gradient brush available is referred to as path gradient. This brush is applied on a path created by connecting a series of points to get a closed shape. The interior of the shape can then be filled as a gradient. To support path brushes, the .NET Framework provides the PathGradientBrush from the System.Drawing.Drawing2D namespace. Two of the constructors of this class are: public PathGradientBrush(Point points[]); public PathGradientBrush(PointF points[]); The argument passed to this constructor is an array of type Point. Here is an example: private void Exercise_Paint(object sender, PaintEventArgs e)
{
Point[] ptGraph =
{
new Point(10, 10),
new Point(450, 10),
new Point(450, 250),
new Point(10, 250)
};
PathGradientBrush pgb = new PathGradientBrush(ptGraph);
e.Graphics.FillRectangle(pgb, 10, 10, 450, 280);
}
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| Previous | Copyright © 2008, yevol.com | Next |
|
|
||