Working with Images
In this section, you will see how to use two of the most common graphic types a programmer interacts with: bitmaps and icons. As stated earlier in the chapter, all user-interface objects in Windows are some form of a bitmap; a bitmap is simply a collection of pixels set to various colors.
The namespace library gives us three classes for working with images: Image, Bitmap and Icon. Image is simply the base class from which the others inherit. Bitmap allows us to convert a graphics file into the native GDI+ format (bitmap). This class can be used to define images as fill patterns, transform images for display, define the look of a buttonits uses are many. Although the bitmap format is used to manipulate images at the pixel level, GDI+ can actually work with the following image types:
Graphics Interchange Format (GIF)
Joint Photographic Experts Group (JPEG)
Exchangeable Image File (EXIF)
Portable Network Graphics (PNG)
Tag Image File Format (TIFF)
Creating an instance of Bitmap requires a filename, stream, or another valid Image instance. For example, the following line of code will instantiate a Bitmap object based on a JPEG file:
Dim myBitmap As New System.Drawing.Bitmap(fileName:="Sample.jpg")
Once instantiated, we can do a number of things with the image. For instance, we can change its resolution with the SetResolution method or make part of the image transparent with MakeTransparent. Of course, we will also want to draw our image to the form. We use the DrawImage method of the Graphics class to output the image to the screen. The DrawImage method has over 30 overloaded parameter sets. In its simplest form, we pass the method an instance of Bitmap and the upper-left coordinate of where we want the method to begin drawing. For example:
myGraphics.DrawImage(image:=myBitmap, point:=New Point(x:=5, y:=5))
Scaling and Cropping
It is often helpful to be able to scale or crop an image to a different size. Suppose you need a 100 x 100 image to fit in a 20 x 20 space, or you want to give your users the ability to zoom in on a portion of an image. You use a variation of the DrawImage method to scale images. This overloaded method takes a Rectangle instance as the destination for drawing your image. However, if the rectangle is smaller or larger than your image, the method will automatically scale the image to match the bounds of the rectangle.
Another version of the DrawImage method takes both a source rectangle and a destination rectangle. The source rectangle defines the portion of the original image to be drawn into the destination rectangle. This, effectively, is cropping. The source rectangle defines how the image gets cropped when applied to the destination. Of course, you can crop to the original size or scale the cropped portion to a new size. Listing 9.8 provides a detailed code example of both scaling and cropping an image.
Listing 9.8 Scale and Crop
Protected Overrides Sub OnClick(ByVal e As System.EventArgs) 'local scope Dim myBitmap As System.Drawing.Bitmap Dim myGraphics As Graphics Dim mySource As Rectangle Dim myDestination As Rectangle 'create an instance of bitmap based on a file myBitmap = New System.Drawing.Bitmap(fileName:="dotnet.gif") 'return the current form as a drawing surface myGraphics = Graphics.FromHwnd(ActiveForm().Handle) 'define a rectangle as the size of the original image (source) mySource = New Rectangle(x:=0, y:=0, Width:=81, Height:=45) 'draw the original bitmap to the source rectangle myGraphics.DrawImage(image:=myBitmap, rect:=mySource) 'create a destination rectangle myDestination = New Rectangle(x:=90, y:=0, Width:=162, Height:=90) 'output the image to the dest. rectangle (scale) myGraphics.DrawImage(image:=myBitmap, rect:=myDestination) 'output a cropped portion of the source myGraphics.DrawImage(image:=myBitmap, _ destRect:=New Rectangle(x:=0, y:=100, Width:=30, Height:=30), _ srcRect:=New Rectangle(x:=0, y:=35, Width:=14, Height:=14), _ srcUnit:=GraphicsUnit.Pixel) End Sub
Notice that we actually drew the image to the form three times. The first time, we drew the image into a rectangle (mySource) based on its original size. The second time, we scaled the image to two times its original size (myDestination) by creating a larger rectangle and outputting the image accordingly. Finally, we cropped a portion of the original output and put it in a new, larger rectangle. Figure 9.5 shows the code's output to the form.
Figure 9.5 Scale and crop output.
An icon in Windows is a small bitmap image that represents an object. You cannot go far in without seeing and working with icons. For example, the File Explorer uses icons to represent folders and files; your desktop contains icons for My Computer, Recycle Bin, and My Network Places.
We use the Icon class to work with icons in .NET. We can instantiate an Icon instance in much the same way we created Bitmap objects. The following code creates an icon based on a file name:
Dim myIcon as New Icon(fileName:="myIcon.ico")
The DrawIcon method of the Graphics class is used to draw the icon to the form. To it, you can pass the icon and either just the upper-left x and y coordinates or a bounding rectangle. If you pass a Rectangle instance, the icon will be scaled based on the bounding rectangle. The following line of code draws an icon object into a bounding rectangle.
myGraphics.DrawIcon(icon:=myIcon, _ rectangle:=New Rectangle(x:=5, y:=5, width:=32, height:=32))
The Graphics class also gives us the DrawIconUnstretched method that allows us to specify a bounding rectangle without actually scaling the icon. In fact, if the icon is larger than the bounding rectangle, it will be cropped to fit from the left corner down and to the right.
Suggestions for Further Exploration
To animate images, take a look at the ImageAnimator class.
Check out the SmoothingMode property of the Graphics class and the SmoothingMode enumeration members. This method allows you to set things like antialiasing to make your graphics look "smoother."