Bitmaps and Metafile

Team-Fly    

 
Application Development Using Visual Basic and .NET
By Robert J. Oberg, Peter Thorsteinson, Dana L. Wyatt
Table of Contents
Chapter 11.  Introduction to GDI+


The .NET Framework makes it very easy to work with images of various sorts. The System.Drawing namespace has the abstract class Image that provides functionality for derived classes such as Bitmap and Metafile . A bitmap stores an image as an array of pixels. A metafile stores an image as a set of drawing commands.

Drawing an Image

The shared method FromFile in the Image class creates an image from a file whose file name is specified by a string. The DrawImage and DrawImageUnscaled methods of the Graphics class can be used to draw an image onto a drawing surface specified by a Graphics object.

graphics/codeexample.gif

The program BitmapDemo illustrates drawing an image that is loaded from a file. You can relocate the image by clicking the mouse, and you can change the image by using the File Open menu command. The standard file open dialog lets you navigate to a folder where the desired image file is stored. The FromFile method supports a number of standard image file formats, including GIF, TIFF, BMP, and JPEG. The Images directory of this chapter contains a few sample images in a number of different formats.

 Public Class Form1    Inherits System.Windows.Forms.Form #Region " Windows Form Designer generated code " ...    Private m_loc As Point    Private m_image As Image    Private m_file As String    Protected Overrides Sub OnMouseDown(_     ByVal e As System.Windows.Forms.MouseEventArgs)       m_loc = New Point(e.X, e.Y)       Invalidate()       MyBase.OnPaint(e)    End Sub    Private Sub Form1_Load(ByVal sender As System.Object, _     ByVal e As System.EventArgs) Handles MyBase.Load       m_file = "..\NET Logo.gif"  m_image = Image.FromFile(m_file)  m_loc = New Point(10, 10)       BackColor = Color.White    End Sub    Protected Overrides Sub OnPaint(_     ByVal e As System.Windows.Forms.PaintEventArgs)       Dim g As Graphics = e.Graphics  g.DrawImageUnscaled(m_image, m_loc)  End Sub    Private Sub mnuFileExit_Click(_     ByVal sender As System.Object, _     ByVal e As System.EventArgs) Handles mnuFileExit.Click       Close()    End Sub    Private Sub mnuFileOpen_Click(_     ByVal sender As System.Object, _     ByVal e As System.EventArgs) Handles mnuFileOpen.Click       Dim dlg As New OpenFileDialog()       dlg.InitialDirectory = "\OI\NetVb"       Dim status As DialogResult       status = dlg.ShowDialog()       If status = DialogResult.OK Then          m_file = dlg.FileName  m_image = Image.FromFile(m_file)  Invalidate()       End If    End Sub End Class 

Saving a Bitmapped Image

Something else you might want to do with images is to create an image file. That is also easy to do with the .NET Framework. You can use drawing commands to create a bitmap by obtaining a Graphics object that is associated with a bitmap. You can then draw to this Graphics object using ordinary drawing commands, and you can then save the bitmap. The following steps outline the general procedure to be followed. A detailed code example is provided in the next section.

  1. Instantiate a Bitmap object.

  2. Obtain a Graphics object using the FromImage shared method of the Graphics class.

  3. Perform drawing commands on the Graphics object.

  4. Call the Save method of the Bitmap class to save the bitmap using a specified image file format.

Drawing Program, Version 3
graphics/codeexample.gif

We illustrate with Version 3 of our drawing program DrawDemo . We can draw rectangles and ellipses as before. We show the bounding rectangle of our drawing with dotted lines. A menu command File Save As Bitmap will save the image as both a BMP and a GIF file. Build and run the program. Figure 11-10 illustrates a drawing consisting of one rectangle and one ellipse.

Figure 11-10. Creating a bitmap using our drawing program.

graphics/11fig10.jpg

When you save, files drawing.bmp and drawing.gif will be created in the same directory as the program executable. You can then examine these files using standard graphics programs. If you have the standard file extension associations, you can double-click on these files in Windows Explorer. You will see the .bmp file displayed in Paint and the .gif file displayed in Internet Explorer.

The program imports the System.Drawing.Imaging namespace and declares member variables to hold a bounding region, a dotted pen, and a bounding rectangle.

 Imports System.Drawing.Drawing2D  Imports System.Drawing.Imaging  ... Public Class Form1    Inherits System.Windows.Forms.Form ...  Private m_region As New Region()   Private m_dotpen As Pen   Private m_bounds As Rectangle  ... 

The load event handler initializes the region to be empty and the pen to be green with a dot style.

 Private Sub Form1_Load(ByVal sender As Object, _  ByVal e As System.EventArgs) Handles MyBase.Load    ...  m_region.MakeEmpty()   m_dotpen = New Pen(Color.Green)   m_dotpen.DashStyle = DashStyle.Dot  End Sub 

A helper method UpdateRegion adds a rectangle determined by two points to the region with the Union method. A bounding rectangle is determined by the GetBounds method, which returns a RectangleF . The Round method is called to obtain the bounding rectangle as a Rectangle .

 Private Sub UpdateRegion(ByVal p As Point, _  ByVal q As Point)    m_region.Union(MakeRectangle(p, q))    Dim g As Graphics = Me.CreateGraphics()    Dim rectf As RectangleF    rectf = m_region.GetBounds(g)    m_bounds = Rectangle.Round(rectf) End Sub 

The OnMouseUp override updates the region using this helper method.

 Protected Overrides Sub OnMouseUp(_  ByVal e As System.Windows.Forms.MouseEventArgs)    m_track = False    m_shape = MakeShape(m_start, m_end, m_type)  UpdateRegion(m_start, m_end)  m_list.Add(m_shape)    Invalidate()    MyBase.OnMouseUp(e) End Sub 

OnPaint draws the bounding rectangle using the green dotted pen.

 Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)    Dim g As Graphics = e.Graphics    Dim objShape As CShape    For Each objShape In m_list       objShape.DrawShape(g)    Next  g.DrawRectangle(m_dotpen, m_bounds)  MyBase.OnPaint(e) End Sub 

Finally, the handler for the menu File Save as Bitmap saves the drawing to a bitmap the size and location of the bounding rectangle, using the steps outlined in the previous section.

 Private Sub mnuFileSaveBitmap_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles mnuFileSaveBitmap.Click    Dim bits As New Bitmap(m_bounds.Right, _       m_bounds.Bottom)    Dim g As Graphics = Graphics.FromImage(bits)    Dim rect As New Rectangle(0, 0, _       m_bounds.Right, m_bounds.Bottom)    g.FillRectangle(Brushes.White, rect)    Dim objShape As CShape    For Each objShape In m_list       objShape.DrawShape(g)    Next    bits.Save("drawing.bmp", ImageFormat.Bmp)    bits.Save("drawing.gif", ImageFormat.Gif) End Sub 

Saving to a Metafile (Version 4)

There is somewhat of a mismatch between the kind of drawing we are creating and the bitmap file formats used for saving the drawing. The drawing itself illustrates vector graphics, and the bitmaps use raster graphics. Another format provided by Windows, called a metafile , allows us to save drawing commands into a file in place of pixels. The resulting file will in general be much smaller than a BMP file. (The GIF file is also small, but it attains its small size through compression, which loses some fidelity. The metafile is an exact representation of the drawing.)

The file format used is enhanced metafile with .emf extension. Like BMP, this file is Windows-specific. Version 4 of our DrawDemo program adds a menu command File Save as Metafile, which will save the drawing as the file drawing.emf in the same folder as the program executable. Here is the code for the menu handler.

 graphics/codeexample.gif Private Sub mnuFileSaveMetafile_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles mnuFileSaveMetafile.Click    'Set up the metafile    Dim gVideo As Graphics = CreateGraphics()    Dim dc As IntPtr = gVideo.GetHdc()    Dim meta As New Metafile("drawing.emf", dc)    gVideo.ReleaseHdc(dc)    gVideo.Dispose()    'Draw to the metafile    Dim g As Graphics = Graphics.FromImage(meta)    Dim rect As New Rectangle(0, 0, _       m_bounds.Right, m_bounds.Bottom)    g.FillRectangle(Brushes.White, rect)    Dim objShape As CShape    For Each objShape In m_list       objShape.DrawShape(g)    Next    g.Dispose() End Sub 

This code is a little more complex than previous examples of GDI+, because working with Windows metafiles requires you to obtain a Windows device context , which up until now has been completely wrapped by the Graphics class. The GetHdc method obtains a handle to a device context (of the .NET data type IntPtr ), and this device context is used as a parameter to the Metafile constructor. A device context is an unmanaged resource, and so we must be careful to explicitly release it by a call to ReleaseHdc . The code also illustrates calling Dispose on our Graphics objects. We have not been careful with using Dispose in our GDI+ programs, but to make them robust, we should do so. We discuss memory management in GDI+ later in the chapter.

The rest of the code is similar to drawing to a bitmap. We use another overloaded version of the Graphics method FromImage , this time passing a metafile rather than a bitmap. We can then use ordinary drawing commands. One difference from the bitmap case is that we have already made the association with the file, and so there is no save step.

Viewing the Metafile

We could write code to view the metafile using additional methods of the Metafile class. But we can view the metafile we've created very simply by using our previous BitmapDemo program. The Image class's shared method FromFile encapsulates many different kinds of file format, including enhanced metafile. Hence you can just run the BitmapDemo program and open the file drawing.emf , and you should see your drawing displayed.


Team-Fly    
Top
 


Application Development Using Visual BasicR and .NET
Application Development Using Visual BasicR and .NET
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 190

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net