• (2 Pages)
  • +
  • 1
  • 2

The wonders of System.Drawing.Graphics

#1 jacobjordan  Icon User is offline

  • class Me : Perfection
  • member icon

Reputation: 113
  • View blog
  • Posts: 1,499
  • Joined: 11-June 08

Posted 12 October 2008 - 10:23 AM

*
POPULAR

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.Graphics

1. 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 object


2. Creating an instance of the Graphics object

Notice if you try to create an instance of the graphics class this way
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
            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:
            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
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:
            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:
System.Drawing.Graphics GraphicsObject = Graphics.FromHwnd(Button1.Handle);

The equivalent of that using the CreateGraphics() method would be to use:
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 know

1. AntiAlias & other Smoothing Modes

The 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 Attached Image (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.Default
Will 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.HighQuality
Will 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.HighSpeed
This will, like the default, specify no smoothing of any kind. I also believe it will produce the same result as the default option.

-- SmoothingMode.Invalid
Will throw an exception if used. Do not specify this option. (Exception will read "Parameter not valid")

-- SmoothingMode.None
Will 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":
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

And to specify Default rendering:
GraphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;


2. Rendering Origin

By 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:
GraphicsObject.RenderingOrigin = new Point(100, 200);


3. Interpolation Modes

Interpolate
in·ter·po·late [in-tur-p[i]uh[/i]-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.Bicubic
Specifies 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.Bilinear
Specifies 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.Default
Will 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.High
Will use a higher quality interpolation than the default. It will also take a bit longer.

-- InterpolationMode.HighQualityBicubic
Will 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.HighQualityBilinear
Will 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.Invalid
Throws an exception.

-- InterpolationMode.Low
Produces a lower quality image than using the default option.

-- InterpolationMode.NearestNeighbor
Will 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":
GraphicsObject.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;


4. Unit of measure

Think 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.Display
Specifies the unit of measure for the display device. If you are drawing on the screen, it will be the same as a pixel.

-- GraphicsUnit.Document
Specifies the document unit as the unit of measure. This is the same as 1/300 of an inch.

-- GraphicsUnit.Inch
Specifies an inch as the unit of measure.

-- GraphicsUnit.Millimeter
Specifies a millimeter as the unit of measure.

-- GraphicsUnit.Pixel
Specifies a pixel as the unit of measure. This is the default value.

-- GraphicsUnit.Point
Specifies a printers point as the unit of measure. This is equivalent to 1/72 of an inch.

-- GraphicsUnit.World
Specifies 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:
            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.Graphics

1. The System.Drawing.Pen

There 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:
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:

-- Width
Determines the width of the pen. We have already discussed this.

-- Color
Specifies the color of the pen.

-- StartCap
Specifies the cap at the starting point of the line.

-- EndCap
Specifies the cap at the ending point of the line.

-- LineJoin
This 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.

-- DashStyle
Specifies the dash style of the pen. It can make the line solid, dashed, dotted, or a combination of dashes and dots.

-- DashCap
Specifies how the end and beginning of dashes and dots will look.

Pen Dash Caps:

(fig 3) Flat (Default):
Attached Image
(fig 4) Round:
Attached Image
(fig 5) Triangle:
Attached Image



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! :P ). 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:
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:
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:
            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.Brush

There 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.SolidBrush
A 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:
            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.TextureBrush
This 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:
            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.Clamp
The image will not be tiled, but stretched to fit the drawing canvas.

-- -- WrapMode.Tile
The image is tiled.

-- -- WrapMode.TileFlipX
The image is mirrored, then tiled.

-- -- WrapMode.TileFlipXY
The image is mirrored and flipped vertically, then tiled.

-- -- WrapMode.TileFlipY
The image is flipped vertically, then tiled.

-- System.Drawing.Drawing2D.LinearGradientBrush
This brush will produce a gradient from one color to another inside the region you are filling. Try this code:
            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:
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.HatchBrush
Ah, 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:
            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:
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.Point

There 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.PointF

This 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.Rectangle

This 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:

--X
We have covered this.

--Y
We have covered this.

--Width
We have covered this.

--Height
We have covered this.

--Size
This 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:
//Example for a size of (100, 50)
r.Width = 100;
r.Height = 50;

One could simply use
//Example for a size of (100, 50)
r.Size = new Size(100, 50);


--Location
Gets a point representing where the upper-left corner of the rectangle is. This can also be set. So, instead of using:
//Example for a location of (100, 50)
r.Left = 100;
r.Top = 50;
One could use
            //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.RectangleF

Point 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 class

In 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
DrawRectangles


2. 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
FillRegion


3. Those that draw images or icons onto the drawing surface. These methods are:
DrawIcon
DrawIconUnstretched
DrawImage
DrawImageUnscaled
DrawImageUnscaledAndClipped


There 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 & Applications

I 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:

Attached File  SimpleDraw.zip (50.66K)
Number of downloads: 7223

This 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. Conclusion

The 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!

Is This A Good Question/Topic? 15
  • +

Replies To: The wonders of System.Drawing.Graphics

#2 gbertoli3  Icon User is offline

  • DIC at Heart + Code
  • member icon

Reputation: 40
  • View blog
  • Posts: 1,162
  • Joined: 23-June 08

Posted 17 October 2008 - 02:54 PM

Great Tutorial!

Five Thumbs Up!
:^: :^: :^: :^: :^:

Finally someone has taken the time to write a really long, but explained step by step process.
Was This Post Helpful? 0
  • +
  • -

#3 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1641
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 17 October 2008 - 02:59 PM

@jacobjordan: If you read it then you seen the "Part 1" part right? There are going to be 4 parts, I just haven't been able to write them yet
Was This Post Helpful? 0
  • +
  • -

#4 wartech  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 203
  • Joined: 16-October 06

Posted 07 January 2009 - 12:42 AM

Great tutorial! Thanks for putting in the work.
Was This Post Helpful? 0
  • +
  • -

#5 lordelf2004  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 10-October 08

Posted 20 March 2009 - 09:35 AM

Great tutorial!! I hope to see more tutorials about Graphics like this! Can I make small game with two car chasing from Graphics class??
Was This Post Helpful? 0
  • +
  • -

#6 StCroixSkipper  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 121
  • Joined: 23-December 08

Posted 20 March 2009 - 10:33 AM

This is a great tutorial! Thanks.
Was This Post Helpful? 0
  • +
  • -

#7 jacobjordan  Icon User is offline

  • class Me : Perfection
  • member icon

Reputation: 113
  • View blog
  • Posts: 1,499
  • Joined: 11-June 08

Posted 21 March 2009 - 12:19 PM

View Postlordelf2004, on 20 Mar, 2009 - 10:35 AM, said:

Great tutorial!! I hope to see more tutorials about Graphics like this! Can I make small game with two car chasing from Graphics class??

Yes you can, though it would have to be a top-down 2D style game, as the graphics class isn't for 3D programming.
Was This Post Helpful? 0
  • +
  • -

#8 sachintha81  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 14-December 08

Posted 26 March 2009 - 11:04 PM

I have some sort of a problem with the Graphics object in C#.

I use a Graphics object of a Panel control to display a summary. In short, I read data on a DGV, then according to that data I draw lines on the Panel. Say, if DGV has three lines with color Red, Blue and Yellow, then I paint three lines on the Panel with the same color. I use the DrawLine() method. If I resize the window (Panel's Anchor property = Top, Bottom, Right), the Panel is drawn again, cos depending on the size of the Panel the height of each line need to be changed. I do this by redrawing the panel on Panel.SizeChanged event.

Everything works fine except for one thing. If I resize the window HORIZONTALLY, and FAST, then what is supposed to be drawn on the panel doesnt draw. If I resize slowly, it does draw the lines on teh Panel accordingly. This happens only when I resize it fast. So I'm guessing this has somehting to do with the execution time of teh Graphics object. Can someone please help?
Was This Post Helpful? 0
  • +
  • -

#9 SanjitVignesh  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 19-September 08

Posted 20 April 2009 - 06:31 AM

Quote

Yes you can, though it would have to be a top-down 2D style game, as the graphics class isn't for 3D programming.


But it is necessary to learn from 2d games, isn't it? You can't directly create 3d games, can you?

This post has been edited by SanjitVignesh: 20 April 2009 - 06:32 AM

Was This Post Helpful? 0
  • +
  • -

#10 levelbkumar  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 03-January 09

Posted 13 November 2009 - 02:32 AM

This was a good Post and I liked. I would Like Some more from the graphics that deals with 3D. Hope u will be of Help. :genius:
Was This Post Helpful? 0
  • +
  • -

#11 Guest_Lukan*


Reputation:

Posted 30 March 2010 - 10:44 AM

Thank you it is a great article by all means Jacob well at least I hope that's your name, I hope to see part 2 thanks again.
Lukan
Was This Post Helpful? 0

#12 IAmCypher  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 38
  • Joined: 14-April 10

Posted 14 April 2010 - 09:19 AM

Hello,

Great guide mate, it did help a lot.

Thanks!

Kind Regards,
IAmCypher
Was This Post Helpful? 0
  • +
  • -

#13 Tanner.R  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 33
  • Joined: 17-April 10

Posted 19 May 2010 - 09:08 PM

Great tutorial! +rep!
:^: :^: :^: :^: :^: :rockon:
Was This Post Helpful? 0
  • +
  • -

#14 shadowstep0705  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 48
  • Joined: 26-May 10

Posted 27 May 2010 - 09:25 AM

nice tutorial! indeed there are not much tutorials about System.Drawing.Graphics
Was This Post Helpful? 0
  • +
  • -

#15 kgraphics  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 11-August 10

Posted 11 August 2010 - 04:20 PM

Awesome introduction to 2D graphics in the .NET framework.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2