Drawing Graphics using PowerShell 1.0 and GDI+

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
Creating GUIs in Windows PowerShell 1.0 with WinFormsUsing COM with Windows PowerShell

Purchase and download the full PDF version of this PowerShell eBook for only $8.99

Windows PowerShell leverages the GDI+ library to provide graphics drawing capabilities. In fact, PowerShell provides the same level of drawing capabilities through GDI+ as those available in other programming languages such as C# and Visual Basic. In fact, those familiar with GDI+ in the context of other programming languages will find the learning curve to be extremely shallow. Those with no previous experience of GDI+ graphics drawing will quickly find that it is both intuitive and easy to learn.


An Overview of GDI+

GDI+ is part of the .NET framwork and is the standard Windows API for working with display hardware to draw graphics on Windows XP, Windows Server 2003 and later Microsoft operating systems. The GDI in GDI+ is an abbreviation for Graphics Display Interface. In terms of using GDI+ within Windows PowerShell it is used in conjunction with WinForms, whereby WinForms provides dialogs, controls and the Form canvas on which the drawing takes place. For more information in WinForms in the context of Windows PowerShell, refer to the chapter entitled Creating GUIs in Windows PowerShell 1.0 with WinForms.

Loading the GDI+ and WinForms .NET Assemblies

As previously mentioned, Windows PowerShell GDI+ development is typically performed in conjunction with WinForms. Neither the GDI+, nor the WinForms .NET assemblies are loaded into the Windows PowerShell environment by default. It is necessary, therefore, to load these assemblies before beginning the development process. GDI+ and Winforms reside in the [Windows.Drawing] and [Windows.Windows.Forms] assemblies respectively. These can be loaded using the following commands:

[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
[reflection.assembly]::LoadWithPartialName( "System.Drawing")

Creating Drawing Objects

Once the appropriate .NET assemblies are loaded, the next step is to create objects with which to draw graphics. The example in this chapter will focus on the Pen and SolidBrush objects. GDI+ provides a range of other drawing objects, details of which are covered in the MSDN .NET documentation.

The following example creates SolidBrush and Pen objects which will be used later in this chapter to perform drawing operations:

$myBrush = new-object Drawing.SolidBrush green
$mypen = new-object Drawing.Pen black

Setting Properties of a GDI+ Drawing Object

Just as with any other object, each GDI+ drawing object contains a set of methods and properties which are accessible from within Windows PowerShell. A full list of available methods and properties of an object may be obtained using the get-member cmdlet. For example,the following command lists all the methods and properties of the $mypen object created in the previous section:

PS C:\tmp> $pen | get-member

   TypeName: System.Drawing.Pen

Name                      MemberType Definition
----                      ---------- ----------
Clone                     Method     System.Object Clone()
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedT...
Dispose                   Method     System.Void Dispose()


Alignment                 Property   System.Drawing.Drawing2D.PenAlignment Alignment {get;set;}
Brush                     Property   System.Drawing.Brush Brush {get;set;}
Color                     Property   System.Drawing.Color Color {get;set;}
CompoundArray             Property   System.Single[] CompoundArray {get;set;}
CustomEndCap              Property   System.Drawing.Drawing2D.CustomLineCap CustomEndCap {get;set;}
CustomStartCap            Property   System.Drawing.Drawing2D.CustomLineCap CustomStartCap {get;...
DashCap                   Property   System.Drawing.Drawing2D.DashCap DashCap {get;set;}
DashOffset                Property   System.Single DashOffset {get;set;}
DashPattern               Property   System.Single[] DashPattern {get;set;}
DashStyle                 Property   System.Drawing.Drawing2D.DashStyle DashStyle {get;set;}
EndCap                    Property   System.Drawing.Drawing2D.LineCap EndCap {get;set;}
LineJoin                  Property   System.Drawing.Drawing2D.LineJoin LineJoin {get;set;}
MiterLimit                Property   System.Single MiterLimit {get;set;}
PenType                   Property   System.Drawing.Drawing2D.PenType PenType {get;}
StartCap                  Property   System.Drawing.Drawing2D.LineCap StartCap {get;set;}
Transform                 Property   System.Drawing.Drawing2D.Matrix Transform {get;set;}
Width                     Property   System.Single Width {get;set;}

With knowledge of these methods and properties, it is possible to change characteristics of an object. For example, the color and width properties of the $mypen object may be modified as follows:

$mypen.color = "red"
$mypen.width = 10

Creating the WinForms Form and the Graphics Object

Having defined the GDI+ drawing objects, the next step is to create a canvas on which to draw. For the purposes of this example, a Winforms Form will act as the drawing canvas. To create this form it is necessary to make use of the WinForms API:

$form = New-Object Windows.Forms.Form

Once the Form has been created, the next step is to create a graphics object on which to draw using the createGraphics() method of the Form object:

$formGraphics = $form.createGraphics()

The Paint Event Handler

Applications with graphical user interfaces are primarily event driven. This means that event handlers must be written to define what actions are to be performed when certain activities occur with regard to the user interface. When a user clicks a button, for example, an event handler performs the necessary tasks associated with that button being pressed (if the button was a Close button, the event handler would be responsible for exiting the application).

In terms of graphics drawing, when a form is displayed a paint event is triggered. Similarly, when a form needs to be repainted (for example because all or part of the form was obscured and then uncovered by another window), the paint event is also triggered. It is, therefore, the job of the paint handler to perform the graphics drawing tasks. A paint event handler is declared in Windows PowerShell via a call to add_paint():

# code or call to a function to perform graphics drawing

Drawing Graphics with Windows PowerShell and GDI+

As outlined in the preceding section, the code to draw the graphics is contained in the paint event handler. In this section we will look at some basic drawing methods.

The following example draws a line from the point at co-ordinates x=10, y=10 to the point at x=190, y=190. It does so using the previously created $myPen object.

$formGraphics.DrawLine($pen, 10, 10, 190, 190)

A filled ellipse is drawn by calling the FillEllipse() method of the graphics object, passing through a suitable drawing object (e.g a brush or a pen) and defining a rectangle into which the ellipse is to fit:

$formGraphics.FillEllipse($myBrush, 20, 20, 180, 180)

A filled ellipse drawn using Windows PowerShell and GDI+

Similarly, a filed rectangle can be drawn using the FillRectange() method, once again passing through a pen or brush and defining the rectangle:

$formGraphics.FillRectangle($myBrush, 0,0,200,200)

A filled rectangle drawn using Windows PowerShell and GDI+

In the above example, rectangles were defined by passing co-ordinates directly through as arguments to the drawing methods. It is also possible to create Rectangle objects:

$rect = new-object Drawing.Rectangle 0, 0, 200, 200

$formGraphics.FillRectangle($myBrush, $rect)

No graphics drawing tutorial would be complete without a single bezier spline, and this chapter is no exception. The following example defines the start, end and two control points of a bezier spline and passes them through, along with a pen object, to the DrawBezier() method of the graphics object:

$p1 = new-object Drawing.Point 10, 100
$p2 = new-object Drawing.Point 100, 10
$p3 = new-object Drawing.Point 170, 170
$p4 = new-object Drawing.Point 200, 100

$formGraphics.DrawBezier($mypen, $p1, $p2, $p3, $p4)

The above script will result in the following:

A Bezier spine drawn using Windows PowerShell and GDI+

Bringing it All Together

Now that we have covered the basic requirements for displaying graphics using Windows PowerShell and GDI+ it is time to bring it all together in a working example. The following script, when executed, will draw a filled green circle and two red lines:

#Load the GDI+ and WinForms Assemblies
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
[reflection.assembly]::LoadWithPartialName( "System.Drawing")

# Create pen and brush objects 
$myBrush = new-object Drawing.SolidBrush green
$mypen = new-object Drawing.Pen black

# Create a Rectangle object for use when drawing rectangle
$rect = new-object Drawing.Rectangle 10, 10, 180, 180

# Create a Form
$form = New-Object Windows.Forms.Form

# Get the form's graphics object
$formGraphics = $form.createGraphics()

# Define the paint handler

$formGraphics.FillEllipse($myBrush, $rect) # draw an ellipse using rectangle object

$mypen.color = "red" # Set the pen color
$mypen.width = 5     # ste the pen line width

$formGraphics.DrawLine($mypen, 10, 10, 190, 190) # draw a line

$formGraphics.DrawLine($mypen, 190, 10, 10, 190) # draw a line


$form.ShowDialog()   # display the dialog

When run, the resulting dialog will appear as follows:

A Windows PowerShell/GDI+ Example