In the few months i have been with Dream in Code, i have noticed a lot of .NET questions have to deal with making paint programs and how to use the Graphics class. Yet, i find there are no tutorials directly relating to the graphics class, which in my opinion is one of the most useful classes in the .NET framework. I looked at PsychoCoder's
Working with the System.Drawing Namespace Part I tutorial, and, to be frank, i was quite disappointed. I discovered it only covered only a fraction of a fraction of how to work with the System.Drawing namespace, and said nothing of System.Drawing.Graphics. In this tutorial, i am writing down all my knowledge of how to work with the wonders of the System.Drawing.Graphics class. Note: I am doing this in .NET 3.5, however i am positive it will also work in .NET 3.0. I am also positive it will work in .NET 2.0, but i am not sure if it will work in .NET 1.0.
I. An introduction to System.Drawing.Graphics1. What is System.Drawing.Graphics?For those of you not familiar with the Graphics class, there is a class in the System.Drawing namespace (System.Drawing.Graphics) that is used for basic or advanced drawing, text rendering, and general graphic manipulation of any control. Before you even read any further, i suggest you open up Visual Studio and browse through the Graphics class with intellisense. You will see there are many methods, most of them beginning with "Draw" or "Fill". With the Graphics class you can:
-- Draw on a control
-- Draw on an Image or Bitmap object2. Creating an instance of the Graphics objectNotice if you try to create an instance of the graphics class this way
csharp
System.Drawing.Graphics GraphicsObject = new Graphics();
that it will not work. The Graphics class has no constructors. The only way to create an instance of the graphics class is through static methods in the graphics class. These methods are:
-- Graphics.FromImage(System.Drawing.Image)That will create a graphics object and assign it to draw on the image you provide. A basic example of this would be
csharp
System.Drawing.Image exampleimage = Image.FromFile("C:\\MyImage.bmp");
System.Drawing.Graphics GraphicsObject = Graphics.FromImage(exampleimage);That will create a graphics object that will draw on the fictional image C:\MyImage.bmp.
Lets use this for real now. First, open up an image editor (it can be anything from Paint to Photoshop) and draw whatever you want on it. Then, save that image as "C:\MyImage.bmp". Open up Visual Studio and make a windows form application. In the load event, put this code:
csharp
System.Drawing.Image exampleimage = Image.FromFile("C:\\MyImage.bmp");
System.Drawing.Graphics GraphicsObject = Graphics.FromImage(exampleimage);
GraphicsObject.FillEllipse(Brushes.Red, new Rectangle(0, 0, 100, 100));
exampleimage.Save("C:\\MyImage2.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
exampleimage.Dispose();
GraphicsObject.Dispose();(We will discuss the FillEllipse method later) That code will create a graphics object from the image you just made. It will then create a new image called C:\MyImage2.bmp. Open that image up in something. You will see a change. There will be a red circle in the upper-left corner of the image that is 100 pixels by 100 pixels. You just edited an image with the graphics class. Keep that instance of Visual Studio open, as we will use it later.
-- Graphics.FromHwnd(IntPtr)That will create a graphics object to paint on a window. Window is just another name for a control. A control can be anything from your form itself to a button to a text box. To use this method, you must pass it the handle to the control. To get the handle to any control, use a property called
Handle. To get the handle to a button called "Button1", use
Button1.Handle. To create a graphics object to draw on that same fictional button, use
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(Button1.Handle)
Now, lets use this in a real situation. In Visual Studio, if you still have some code in your load event from the last example, clear it out. Make a
Shown (not Load) event for your form. In that event, put:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.FillEllipse(Brushes.Red, new Rectangle(0, 0, 100, 100));
That will draw a red circle in the upper-left corner of your form when is is shown. Notice we used the same FillEllipse method used in the image scenario. It will draw a red 100x100 circle. Now, run your application. You should see the circle. Now, move your form off the screen, so that part of the circle is hidden. When you move it back, you will see that the part of the circle you just moved away is gone! That is because that area of your form redrew itself, so anything you drew in that area vanishes. To correct that in this example, create a paint event for your form. A paint event will run through any time any part of your control (form in this case) redraws itself. Put the same code as you put in the shown event in that paint event. Then, run the app and do anything you want with the form. Resize it, move it off the screen, anything, the circle will always be there. That is because now, any time your form redraws any part of itself, it will also redraw the circle.
Another way to create a graphics object from a control is to use the CreateGraphics() method all controls have. Here is the code that will create a graphics object for a control called Button1 again:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(Button1.Handle);
The equivalent of that using the CreateGraphics() method would be to use:
csharp
System.Drawing.Graphics GraphicsObject = Button1.CreateGraphics();
The same can be done in the form scenario. Just use
this.CreateGraphics() to create a graphics object for your form.
II. Stuff you need to know1. AntiAlias & other Smoothing ModesThe graphics class has a host of methods which can let you draw anything from an open circle to a filled square. In advanced drawing application such as GIMP, Paint Shop Pro, and Photoshop, you may have heard the term "Anti Alias" (or just "AntiAlias"). For example, there may have been a check box that said "Use AntiAlias Rendering". If you don't already know what that means, when you draw a figure using AntiAlias rendering, it will smooth the edges to fit into the background.
AntiAlias'ing a Circle: *
(fig 1) Without
(fig 2) With*Pixels enlarged to show detail
*Image made with Paint Shop Pro, not with the graphics class
The Graphics class can also either draw with or without AntiAlias'ing. There is a property in the graphics class called
SmoothingMode. That property can be set to one of the following:
-- SmoothingMode.AntiAlias Will specify that any object drawn with that graphics class will use AntiAlias smoothing.
-- SmoothingMode.DefaultWill specify that no smoothing of any kind is to be used. This will make figures that are drawn to resemble the figure in the Without AntiAliasing example above.
-- SmoothingMode.HighQualityWill specify high quality, and low speed rendering and smoothing. I am not sure if this will produce a result any different than using the AntiAlias option, as i have used both and the results they produce look virtually identical.
-- SmoothingMode.HighSpeedThis will, like the default, specify no smoothing of any kind. I also believe it will produce the same result as the default option.
-- SmoothingMode.InvalidWill throw an exception if used. Do not specify this option. (Exception will read "Parameter not valid")
-- SmoothingMode.NoneWill produce the same result as if you used either the Default or HighSpeed option.
Just so were all clear, here is an example on how to specify AntiAlias rendering in a graphics object called "GraphicsObject":
csharp
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
And to specify Default rendering:
csharp
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
2. Rendering OriginBy default, when we create a new graphics class for a control or an image, the rendering origin is set at the top-left corner of the image or control (0, 0). The
Rendering Origin is like the origin on a X, Y graph. Actually, it is exactly like the origin on an X, Y graph. Think of the image or control you are drawing on as a graph. The rendering origin is the origin of that graph. When you want to draw something, you have to input the location where you want to draw it at. That point you input is in relation to the Rendering Origin. If the rendering origin is set at the control's or image's top-left corner (0, 0) and you tell it to draw a circle at point (50, 50), then it will draw a circle 50 pixels away from the top and 50 pixels from the left. However, if you set the rendering origin to (100, 100), and you choose to draw the same circle at point (50, 50), then that circle will be draw 150 pixels from the top and 150 pixels from the left.
To change the rendering origin of a graphics object, there is a property called, well,
RenderingOrigin. Like i said, by default this is set at (0,0). You can change it to anything you want. Just to be clear on this, to change the rendering origin of a graphics object called GraphicsObject to (100, 200), you would use:
csharp
GraphicsObject.RenderingOrigin = new Point(100, 200);
3. Interpolation ModesInterpolatein·ter·po·late
[in-tur-puh-leyt]to introduce (something additional or extraneous) between other things or parts; interject; interpose; intercalate.
There is another property in the graphics class called
InterpolationMode. In addition to being able to draw circles and squares and lines and text with a graphics object, you can also draw images themselves onto graphics object. However, you might want to change the image's size before you draw it. For example, if you had an image that was 20 by 20, and you wanted to draw it in an area of 100 by 100, then you would have to scale up the image. This property specifies what algorithm will be used to do this. Like the definition said, "Interpolation" is introducing new things between others. When you scale up and image, you have to introduce new pixels between the already known ones to produce the final result. By changing this property, you can change the quality of how this is done. Here are the possible values this property can take:
-- InterpolationMode.BicubicSpecifies that the Bicubic algorithm will be used when scaling the image. This will produce a bad result if you are shrinking the image below 25% of it's origninal size.
-- InterpolationMode.BilinearSpecifies that the Bilinear algorithm will be used when scaling the image. This will produce a bad result if you are shrinking the image below 50% of it's origninal size.
-- InterpolationMode.DefaultWill use a low quality algorithm in resizing an image. Like the name suggests, this is the default value givin to the InterpolationMode property when you create a new graphics object.
-- InterpolationMode.HighWill use a higher quality interpolation than the default. It will also take a bit longer.
-- InterpolationMode.HighQualityBicubicWill use a very high quality Bicubic algorithm in resizing the image. This will produce a high quality sized image, whether you are shrinking or enlarging it. This produces the highest quality transformed image. However, it also takes the longest.
-- InterpolationMode.HighQualityBilinearWill use a very high quality Bilinear algorithm in resizing the image. This will produce a high quality sized image, whether you are shrinking or enlarging it, but not as good as the HighQualityBicubic.
-- InterpolationMode.InvalidThrows an exception.
-- InterpolationMode.LowProduces a lower quality image than using the default option.
-- InterpolationMode.NearestNeighborWill use Nearest-Neighbor (also called Pixel Resize) interpolation. This turns off any smoothing that may be used on the image. This is not good for shrinking an image, and if you are resizing an image up it will produce a blocky image. This is very useful if you are creating an image editing application where you need to resize up the image so you can see the individual pixels that made up the original, as that is exactly what this does.
And again, to be clear, i will give an example on how to change this mode to HighQualityBicubic for a graphics object called "GraphicsObject":
csharp
GraphicsObject.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
4. Unit of measureThink back to when we discusses the rendering origin. I said that if the rendering origin was set at (50, 50), then the origin would be 50 pixels off the left of the object you are drawing on and 50 pixels off the top of the object you are drawing on. However, there is a property in the graphics class called
PageUnit. It determines the unit of measure when you draw something. So, if the graphics unit is set at pixels, and the rendering origin was at (50, 50), then the origin would be 50 pixels off the left and 50 pixels off the top. However, if the graphics unit was set to inch, then then the rendering origin would be 50 inches off the left and 50 inches off the top. Be default, it is set to
GraphicsUnit.Pixel.
Here are the values it can take:
-- GraphicsUnit.DisplaySpecifies the unit of measure for the display device. If you are drawing on the screen, it will be the same as a pixel.
-- GraphicsUnit.DocumentSpecifies the document unit as the unit of measure. This is the same as 1/300 of an inch.
-- GraphicsUnit.InchSpecifies an inch as the unit of measure.
-- GraphicsUnit.MillimeterSpecifies a millimeter as the unit of measure.
-- GraphicsUnit.PixelSpecifies a pixel as the unit of measure. This is the default value.
-- GraphicsUnit.PointSpecifies a printers point as the unit of measure. This is equivalent to 1/72 of an inch.
-- GraphicsUnit.WorldSpecifies the world coordinate system as the unit of measure. This will throw an exception if used.
Now, you should still have Visual Studio open. Clear all the code out of your class. Then, make a paint event for your form. Put this code in it:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.Pen redpen = new System.Drawing.Pen(Color.Red, 1);
GraphicsObject.PageUnit = GraphicsUnit.Pixel;
GraphicsObject.DrawLine(redpen, new Point(0, 0), new Point(50, 50));
Run your application. You will see there is a thin 1-pixel wide 50-pixels long red line in the top-left of your form. Close your form. In the code in your paint event, see the line that says
GraphicsObject.PageUnit = GraphicsUnit.Pixel? Change that so it reads
GraphicsObject.PageUnit = GraphicsUnit.Inch. Run your application again. You will see that the red line is not 1-pixel wide, but 1 inch wide. And it is not 50 pixels long, but 50 inches long. Unless you happen to have a 50'' monitor, you will not be able to see all of the 50 inch long line, but believe me, it's there. Now, change that line so it reads
GraphicsObject.PageUnit = GraphicsUnit.Millimeter. Run your application again. Now, that line that used to be an inch wide is now 1 millimeter wide, and 50 millimeters long. Keep that code in your paint event, and again, keep Visual Studio open as we will use it later.
IV. Classes related to System.Drawing.Graphics1. The System.Drawing.PenThere are a few drawing methods in the graphics class i need to inform you of now:
-- DrawArc
-- DrawBezier
-- DrawBeziers
-- DrawClosedCurve
-- DrawCurve
-- DrawEllipse
-- DrawLine
-- DrawLines
-- DrawPath
-- DrawPie
-- DrawPolygon
-- DrawRectangle
-- DrawRectangles
We will discuss how to use the methods later. Before that, i need to teach you about a class called System.Drawing.Pen. All of these methods have something in common; they will all draw open figures. By open, i mean they are comprised of lines that can be curved and intersect one another at various points to form the final figure. Let's take the DrawLine method for example. That is probably the most basic drawing method in the whole graphics class. It will draw a straight line defined by a starting and ending point. It takes three arguments: the starting point, the ending point, and a Pen. The pen will determine what the line will look like (width, color, etc). Declare a new pen:
csharp
System.Drawing.Pen redpen = new System.Drawing.Pen(Color.Red);
That will declare a new pen with a width of 1 and a color of red. By width of 1, i mean width of 1 unit of measure used by the graphics object that will use this pen. If the graphics object that is going to use this pen has a graphics unit of inch, then the pen will have a width of 1 inch. If the graphics object has a graphics unit of pixel, the the pen is one pixel wide. Browse through the pen with intellisense. There are many properties which can determine how the pen will look. Here are the main ones:
-- WidthDetermines the width of the pen. We have already discussed this.
-- ColorSpecifies the color of the pen.
-- StartCapSpecifies the cap at the starting point of the line.
-- EndCapSpecifies the cap at the ending point of the line.
-- LineJoinThis is used when you draw several lines one connecting to the end of the other. It specifies how the joint between the lines will look.
-- DashStyleSpecifies the dash style of the pen. It can make the line solid, dashed, dotted, or a combination of dashes and dots.
-- DashCapSpecifies how the end and beginning of dashes and dots will look.
Pen Dash Caps:
(fig 3) Flat (Default):

(fig 4) Round:

(fig 5) Triangle:

Now, remember the example we did from the last section? You know, discussing graphics units. I instructed you to leave that code in your paint event, and here we are going to use it to help to explain how to use a pen. You should see i declared a pen called
redpen, it is on the line that reads
System.Drawing.Pen redpen = new System.Drawing.Pen(Color.Red);. I named it redpen, because it is red! (wow, that genius!

). Your graphics unit for that graphics object should still be set to millimeter. Add this line of code right after you declared the pen variable:
csharp
redpen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
Run your program. You will see there is a 1 millimeter wide dotted line. Close your form. Play around with the DashStyle property a bit to see what all the different line styles look like. Now, change it back to DashStyle.Dash. Add this line of code right after that one:
csharp
redpen.DashCap = System.Drawing.Drawing2D.DashCap.Triangle;
Run your application again. You will be able to make out a triangle cap on the end of the dashes, resembling fig. 6. You may want to change your graphics unit to inch or increase the pen's width to 3 or 4 to see the cap a bit better. Play around with the DashCap property to see the different caps.
Change your pen's dash style back to solid. It's time to put some caps on your line. Clear all the code out of the paint event. Now, put this code in it:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.Pen redpen = new System.Drawing.Pen(Color.Red, 5);
//These are the lines that change the pen's starting and ending caps
redpen.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor; //round starting cap
redpen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor; //diamond ending cap
/******************************************************************/
GraphicsObject.PageUnit = GraphicsUnit.Millimeter;
GraphicsObject.DrawLine(redpen, new Point(20, 20), new Point(50, 50));
Run your application again. You will see there is a line in the center of your form. It has a ball-like starting cap and a square like ending cap. Play around with those a bit until you feel confident you have a good understanding of what each of the caps looks like. Keep Visual Studio open, but clear the code out of the paint event. We are about to introduce you the pen's brother.
2. The System.Drawing.BrushThere are a few more drawing methods in the graphics class i need to inform you of now:
-- FillClosedCurve
-- FillEllipse
-- FillPath
-- FillPie
-- FillPolygon
-- FillRectangle
-- FillRectangles
-- FillRegion
Again, i will discuss these later. These methods have something in common. They will draw shapes, not lines. For example, the FillEllipse method will draw a closed circle. This is similar to the DrawEllipse method, the only difference is that the DrawEllipse method draw an open circle comprised of a curved line, and the FillEllipse method draws a closed circular figure. The DrawEllipse method took an argument of a Pen which would define what the line would look like. The FillEllipse method takes a Brush object to define what the closed figure will look like. There are a lot more options when creating a filled shape, because then you can have thing like gradients and textures. Just as the pen determines what a line will look like, the Brush will determine how a filled region looks. Actually, the System.Drawing.Brush is nothing but an abstract class. There are other classes that inherit from it. These classes are:
-- System.Drawing.SolidBrushA brush of a solid color. This class requires very little explaining. It only contains one property, the color. For an example on how to use the SolidBrush, put this code in your paint event:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.SolidBrush RedSolidBrush = new SolidBrush(Color.Red);
GraphicsObject.PageUnit = GraphicsUnit.Millimeter;
GraphicsObject.FillEllipse(RedSolidBrush, new Rectangle(5, 5, 50, 50));
We declared the solidbrush on line 2 of that code. That's about it for the features of the solid brush, all it does is specify the color to fill the inside of a shape with.
-- System.Drawing.TextureBrushThis is my personal favorite of all the brushes. It takes an image, and uses that to fill the inside of a shape, not a color. Use this code in your paint event:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.TextureBrush Texture = new TextureBrush(Image.FromFile( /*put the path to an image on your computer here*/ ));
/******************************************************************/
GraphicsObject.PageUnit = GraphicsUnit.Millimeter;
GraphicsObject.FillEllipse(Texture, new Rectangle(5, 5, 100, 100));
Like it implies, replace the part that says "/*put the path to an image on your computer here*/" with a string path to an image on your computer. Any image. Run your program and see what happens. There is also a property in the texturebrush we need to discuss. It is called WrapMode. It specifies how the image will be tiled on the surface you are drawing on. It can take one of the following:
-- -- WrapMode.ClampThe image will not be tiled, but stretched to fit the drawing canvas.
-- -- WrapMode.TileThe image is tiled.
-- -- WrapMode.TileFlipXThe image is mirrored, then tiled.
-- -- WrapMode.TileFlipXYThe image is mirrored and flipped vertically, then tiled.
-- -- WrapMode.TileFlipYThe image is flipped vertically, then tiled.
-- System.Drawing.Drawing2D.LinearGradientBrushThis brush will produce a gradient from one color to another inside the region you are filling. Try this code:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.Drawing2D.LinearGradientBrush gradient = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(5, 5, 100, 100), Color.Red, Color.Green, 0);
/******************************************************************/
GraphicsObject.PageUnit = GraphicsUnit.Millimeter;
GraphicsObject.FillEllipse(gradient, new Rectangle(5, 5, 100, 100));
When you run that, you will see there is a circle that is red on the left, and fades to green on the right. Here is how we declared the gradient brush used to paint that:
csharp
System.Drawing.Drawing2D.LinearGradientBrush gradient = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(5, 5, 100, 100), Color.Red, Color.Green, 0);
The first argument is the space the gradient will take up. If the space the gradient takes up is less than the size of the region to be filled, then the gradient is tiled like an image. The next argument is the starting color, red in this case. The next is the ending color, green in this case. The next is the angle at which the gradient will be shown. Zero produces a horizontal gradient, like the one in the example. Change the angle to 45, and it produces a top-left to bottom-right diagonal gradient. Change it to 90 degrees, and it produces a top to bottom vertical gradient.
-- System.Drawing.Drawing2D.HatchBrushAh, i love this brush too. It will draw a pattern in the region to be filled. To see what i'm talking about, put this code in your paint event:
csharp
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(this.Handle);
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
System.Drawing.Drawing2D.HatchBrush pattern = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SolidDiamond, Color.Red, Color.Green);
/******************************************************************/
GraphicsObject.PageUnit = GraphicsUnit.Millimeter;
GraphicsObject.FillEllipse(pattern, new Rectangle(5, 5, 100, 100));
That particular arrangement will produce a diamond-weave like red and green texture. Let's take a look at the constructor i used to make that brush:
csharp
System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SolidDiamond, Color.Red, Color.Green);
The first argument is the most important. It is the pattern that will be used when drawing with the brush. In my example, i used the HatchStyle.SolidDiamond pattern, which produced the diamond like texture. There are over 50 different patterns that can be used, and there's no way i'm going to explain all of them in this tutorial. Simply play around, see what the different patterns look like. The next argument is called the Foreground Color. A pattern produced by this brush is comprised of two colors, the foreground color is simply the first of those colors. In this one, it is red. The next argument is called the background color. It is the second color in the pattern.
3. The System.Drawing.PointThere is one thing i want to go over really quick here. In the unlikely event you have never heard of a Point, is is a simple struct with only 2 properties. It specifies a point on a 2D plane, defined by X and Y coordinates. This is used quite frequently throughout the graphics class and in .NET programming in general.
3.5 The System.Drawing.PointFThis is very similar to the System.Drawing.Point, with only one difference. The System.Drawing.Point uses two
ints call X and Y to specify a location in 2D space. The PointF struct uses two
floats called X and Y to specify a location in 2D space. It's that simple. In fact, PointF stands for "PointFloat".
4 The System.Drawing.RectangleThis is another quick struct i want to go over. The rectangle is similar to the point in the respect that is has an X and Y property for the upper-left corner of the rectangle, however it also has two properties called Width and Height. The rectangle is used to specify a, well, a rectangle. A 2D rectangle in space. There are quite a few more properties in the rectangle class, and i would like to go over them:
--XWe have covered this.
--YWe have covered this.
--WidthWe have covered this.
--HeightWe have covered this.
--SizeThis property can be used to obtain a System.Drawing.Size of how big the rectangle is based on its width and its height. It can also be set, so instead of doing something like this:
csharp
//Example for a size of (100, 50)
r.Width = 100;
r.Height = 50;
One could simply use
csharp
//Example for a size of (100, 50)
r.Size = new Size(100, 50);
--LocationGets a point representing where the upper-left corner of the rectangle is. This can also be set. So, instead of using:
csharp
//Example for a location of (100, 50)
r.Left = 100;
r.Top = 50;
One could use
csharp
//Example for a location of (100, 50)
r.Location = new Point(100, 50);
--Right This is readonly. It will get the sum of the X coordinate and the Width of the rectangle, so basically it returns the X coordinate of the right side of the rectangle.
--Bottom This is readonly. It will get the sum of the Y coordinate and the Height of the rectangle, so basically it returns the Y coordinate of the bottom side of the rectangle.
There are also a few methods in the rectangle struct i want to cover:
--Inflate(Size)This will add the specified size to the rectangle's size. If the rectangle's size is (100, 50), and you inflate it by (10, 10), the rectangle's new size will be (110, 60).
--IntersectsWith(Rectangle)Sees if the rectangle you provided as a parameter intersects with the rectangle you called the method from. This can be useful if you are creating a pong game, for example.
--Offset(int, int)Will offset the rectangles location. The first parameter says how much to offset the X property, and the second says how much to offset Y.
4.5 The System.Drawing.RectangleFPoint is to PointF as Rectangle is to RectangleF. Makes sense, doesn't it? The only difference between the Rectangle and the RectangleF is that the X, Y, Width, and Height properties take floats, and not ints. Also, the Inflate method will take a SizeF, and not a Size. The Offset method will take two floats, and not two ints.
III. Drawing methods of the Graphics classIn the Graphics class, you will notice there are many methods that begin with "Draw" or "Fill". There are three basic types of drawing methods in the Graphics class:
1. Those that draw figures consisting of different lines. These methods usually begin with "Draw" and take Pens that define the style of the lines. These methods are:
DrawArc
DrawBezier
DrawBeziers
DrawClosedCurve
DrawCurve
DrawEllipse
DrawLine
DrawLines
DrawPath
DrawPie
DrawPolygon
DrawRectangle
DrawRectangles2. Those that draw closed, filled shapes. These methods usually begin with "Fill" and take a Brush that defines how the interior of the shape will be filled with the color, texture, pattern, or gradient. These methods are:
FillClosedCurve
FillEllipse
FillPath
FillPie
FillPolygon
FillRectangle
FillRectangles
FillRegion3. Those that draw images or icons onto the drawing surface. These methods are:
DrawIcon
DrawIconUnstretched
DrawImage
DrawImageUnscaled
DrawImageUnscaledAndClippedThere is, however, one method that doesn't fit into any of those categories. It is the DrawString method. It is used to draw text onto the drawing surface. There are several different overloads for this method, but basically it will take the string with the text you wish to draw, the font you want it drawn in, and the Brush you want to draw it with. Because it takes a brush and not a pen, this means you can draw textured, gradient, or patterned text.
V. Examples & ApplicationsI feel it necessary to provide a real-life example of how to use all these methods and classes i've been explaining. I have a very simple application:
SimpleDraw.zip ( 50.66k )
Number of downloads: 1341This is a very simple <200 line drawing application, however it demonstrates how to draw with both brushes and pens. It also demonstrates how to draw on both an image and a control. The code for the main form is probably ~50% comments, as i wanted to thoroughly explain what was happening.
VI. ConclusionThe System.Drawing.Graphics class truly has some amazing abilities. Once you master them, you will be able to create painting programs with amazing features. You will learn more by experimenting with the System.Drawing.Graphics class and making paint programs by yourself than you ever will by reading this tutorial or any book. Reading how to do something will not teach you near as much unless you actually do it. So, go make something!