Images. Part 1

Image manipulation in GDI+ is straightforward and powerful. The Image class provides a container for many diverse image formats and the Graphics object all of the basic functionality needed to display the pictures. Like so many of the .NET framework objects, Image is an abstract base class from which concrete classes are derived. The principal class used in GDI+ is the Bitmap class.

The characteristics of an image are as follows:

  • Pixel-dimensions. The logical size of an image is defined by its pixel dimensions expressed as width and height. These values represent the number of individual picture-cells across or down the image from it's origin.

  • Pixel depth. The number of bits of information that are used to describe one picture cell. The more bits there are in this measurement the more shades of colour an image can display. Most images are displayed in a minimum of 24 bits per-pixel which provides 8 bits each of red, green and blue. This means that any individual pixel can show any one of 16,777,216 different colours. There are also indexed image types that use a palette to provide colour selections. These will be discussed in a later article.

  • Pixel resolution. This is the measure of how many pixels in the image are displayed per linear inch of screen or printer area. The physical size of an image when viewed will rely on the pixel resolution and the size of the image.

An image can be obtained from disk using the Image.FromFile method. This enables you to nominate a file such as a .JPG or .TIFF and load it into an object in memory. Note that the image decoder worries about the different file formats so you don't have to. Once you have the image you can display it using the Graphics.DrawImage method. In the following simple application I have used an image from my C: drive and displayed it on a form. Figure 1 shows the application working and the following listing shows the code for the application.

Figure 1. Drawing an image.

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

namespace drawimage1

{

  /// <summary>

  /// Summary description for Form1.

  /// </summary>

  public class Form1 : System.Windows.Forms.Form

  {

    Image myImage;

 

    public Form1()

    {

    }

 

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main()

    {

      Application.Run(new Form1());

    }

 

    protected override void OnLoad(EventArgs e)

    {

      myImage=Image.FromFile(@"C:\bob.jpg");

      base.OnLoad (e);

    }

 

    protected override void OnPaint(PaintEventArgs e)

    {

      if(myImage!=null)

        e.Graphics.DrawImage(myImage,0,0);

      base.OnPaint (e);

    }

 

  }

}

 

 

Imports System

Imports System.Drawing

Imports System.Collections

Imports System.ComponentModel

Imports System.Windows.Forms

Imports System.Data

 

 

Namespace drawimage1

   '/ <summary>

   '/ Summary description for Form1.

   '/ </summary>

  

   Public Class Form1

    Inherits System.Windows.Forms.Form

    Private myImage As Image

    

    

    Public Sub New()

    End Sub 'New

    

    

    '/ <summary>

    '/ The main entry point for the application.

    '/ </summary>

    <STAThread()>  _

    Shared Sub Main()

     Application.Run(New Form1())

    End Sub 'Main

    

    

    Protected Overrides Sub OnLoad(e As EventArgs)

     myImage = Image.FromFile("C:\bob.jpg")

     MyBase.OnLoad(e)

    End Sub 'OnLoad

    

    

    Protected Overrides Sub OnPaint(e As PaintEventArgs)

     If Not (myImage Is Nothing) Then

      e.Graphics.DrawImage(myImage, 0, 0)

     End If

     MyBase.OnPaint(e)

    End Sub 'OnPaint

   End Class 'Form1

End Namespace 'drawimage1

The application loads the image in the OnLoad handler and paints it in the OnPaint handler.

You can see that the DrawImage command used simply draws the image with the top-left corner of the image at the X and Y coordinate provided. This no-frills way of displaying a picture is very convenient if the picture is the right size and you don't need to change anything about it. DrawImage is however massively overloaded with a list of options as long as your arm so hang onto your hats whilst we explore some of the things you can use it for.

Destination and Source.

The Drawimage command is often used to display an image in a specific place specified as a destination rectangle. Declaring the position and size of the resulting image is accomplished using the location and size of a Rectangle structure. The code shown in the first listing can be modified to shoe-horn the image into a specific destination rectangle as shown in figure 2.

Figure 2. A somewhat distorted image.

The change that displayed the image in this way is shown in the following listing.

    protected override void OnPaint(PaintEventArgs e)

    {

      if(myImage!=null)

        e.Graphics.DrawImage(myImage,new RectangleF(20,20,50,130));

      base.OnPaint (e);

    }

 

    Protected Overrides Sub OnPaint(e As PaintEventArgs)

     If Not (myImage Is Nothing) Then

        e.Graphics.DrawImage(myImage, New RectangleF(20, 20, 50, 130))

     End If

     MyBase.OnPaint(e)

    End Sub 'OnPaint

 

You can see that specifying a destination forces pixels to be squeezed or stretched to accommodate the desired area. The example above however, uses the whole image as it's source, this is the default. If we specify a source area too then it's possible to take any portion of an image and display it in any place and at any distortion factor. Figure 3 shows the source selection of the image and figure 4 shows the displayed picture after having the source area selected and copied, or "Blitted" to the destination.

Figure 3. The selection area.

Figure 4. The result of blitting a source to a destination.

The DrawImage code in the OnPaint routine was replaced with the following:

 e.Graphics.DrawImage(myImage,

                    new RectangleF(20, 20, 50, 130),

                    new RectangleF(206, 46, 62, 73),

                    GraphicsUnit.Pixel);
 

 e.Graphics.DrawImage(myImage,

                  New RectangleF(20, 20, 50, 130), _

                  New RectangleF(206, 46, 62, 73), _

                  GraphicsUnit.Pixel)
 

Summary.

In this article you've seen how to load an image and how to draw it in it's entirety or only selected portions of it. The Graphics.DrawImage method is heavily overloaded, take a while to study the possibilities in the MSDN help files.

Return to the beginners guide index.