Generate and Modify Images with GDI+

ost Windows applications need to use graphics or images to let users work with the images directly, or to enhance the user experience. Most applications can accomplish this with static image data, without modifying the image files or manipulating the data on screen. For some applications such as a document management system that may need to render an underlying graphics file for a scanned document in many different ways, the need to modify the image data is critical. With GDI+, the Windows graphic design interface, and the .NET Framework you can develop applications to manipulate image data to suit your needs. You’ll find the classes and methods you need in the .NET Framework in the System.Drawing namespace.

What You Need
To build the example included with this article, you should have a basic understanding of the .NET Framework and C#. You’ll need Visual Studio .NET and the .NET Framework SP1.

To leverage GDI+ and its supported imaging functions in your applications, you should develop a basic understanding of GDI+ and how the .NET framework supports its imaging functionality. You should also familiarize yourself with the Image, Graphics, and Bitmap classes available in the System.Drawing and System.Drawing.Imaging namespaces. These classes support image data management and modification. In this article, you’ll see how to construct a sample application that uses these classes to load, modify, and save image data. Specifically, the sample code demonstrates image conversion, placing text on an image, cropping, and image rotation. You’ll also see how to apply these techniques in a Windows forms application to display and manipulate images dynamically.

GDI+ supports several image file formats natively, including jpeg, bmp, gif, tiff and others, as well as common image transformation operations such as cropping, rotation, flipping, and image adjustments for contrast, brightness, and blurring. The architecture is extensible, so you can add new image formats if necessary.

Important GDI+ Classes
The Image class supports numerous functions for dealing with image data. The Bitmap class, derived from the Image class, holds the pixel data for an image and also manages related image attributes. You’ll most commonly dealing with pixel-based raster images by creating a Bitmap instance. In the System.Drawing.Imaging namespace, you can use the ImageFormat class to specify the image format. The Image class uses an ImageFormat instance as an input parameter to specify the format for functions that save images or translate images between formats.

While the Bitmap and Image classes support much of the native imaging functions, some manipulations require you to use the drawing functions available through the Graphics class. Specifically, you can use the Graphics.DrawImage method to render an image based on an instance of an Image object, drawing it to a specified location at a specified size based on the input parameters provided to the function. The sample Windows forms application that accompanies this article demonstrates the power of these imaging functions for image manipulations.

Basic Image Manipulation
The sample form contains five button controls and one picture box control. The buttons initiate various image manipulation functions. The picture box displays the original image when the form first loads and the modified image after each manipulation. The application uses the sample image sample.gif for all image manipulations, so you’ll need to copy the file to your hard disk, and then change the value of the constant strFileName so that it contains the pathname of the copied sample.gif file on your machine.

Loading Images
The simplest way to load an image is to call the System.Drawing.Image.FromFile method with the pathname of the file you want to load, for example:

   img = System.Drawing.Image.FromFile(strFileName);

The FromFile method returns an Image object, which you can then manipulate or assign to the Image property of a PictureBox control.

   pbImage.Image = img;

The method has a second optional Boolean parameter, with the exceptionally long name of useEmbeddedColorManagement, which controls whether the Image object uses any color correction information embedded in the file. The default value of the parameter is false.

Cropping Images
The Click event-handler for the btnCrop button in the sample code shows how to crop an image. First, create an instance of an image object in the code and load the sample image file into an Image object. To crop the image, create a Bitmap instance containing the image data, and then create Rectangle objects with the source (recCrop) and destination (recDest) dimensions defined for the desired crop area. After creating the Bitmap and rectangles, you pass the Bitmap and rectangles to the Graphics class’s DrawImage method to draw the cropped image:

gphCrop.DrawImage(bmpImage, recDest,

recCrop.X, recCrop.Y,

recCrop.Width, recCrop.Height,

GraphicsUnit.Pixel);

Now you can save the cropped Bitmap as a new image file and load it into the picture box control on the form (see Figure 1) as follows: .

      bmpCrop.Save(Application.StartupPath +         cstrCropFileName);         pbImage.Image = bmpCrop;
Figure 1: Sample image loaded into a PictureBox control on a form.

Here’s the complete code. Note how it uses the Bitmap, Rectangle, and Graphics objects to perform the cropping function.

   private void btnCrop_Click(object sender,       System.EventArgs e)   {         const string cstrCropFileName =          "\Crop_Sample.gif";                  System.Drawing.Image img;                  img = System.Drawing.Image.FromFile(strFileName);                  Bitmap bmpImage = new Bitmap(img);         Rectangle recCrop = new Rectangle(0, 0,          bmpImage.Width/2, bmpImage.Height/2);         Bitmap bmpCrop = new Bitmap         (recCrop.Width/2, recCrop.Height/2,          bmpImage.PixelFormat);         Graphics gphCrop =          Graphics.FromImage(bmpCrop);         Rectangle recDest = new Rectangle(0, 0,          bmpImage.Width/2,bmpImage.Height/2);         gphCrop.DrawImage(bmpImage, recDest,          recCrop.X, recCrop.Y,         recCrop.Width, recCrop.Height,          GraphicsUnit.Pixel);         bmpCrop.Save(Application.StartupPath +         cstrCropFileName);         pbImage.Image = bmpCrop;      }

Creating Thumbnail Images
You can use a similar technique to create a true thumbnail of your image. The Image class supports a GetThumbnailImage method which generates thumbnails. For example:

      const string cstrThumbFileName =          "\Thumb_Sample.gif";                  System.Drawing.Image img =          System.Drawing.Image.FromFile      (strFileName);         System.Drawing.Image.GetThumbnailImageAbort          imgCallBack = new          System.Drawing.Image.GetThumbnailImageAbort         (CallBackMethod);         System.Drawing.Image imgThumbnail =       img.GetThumbnailImage(img.Width/4,       img.Height/4, imgCallBack, IntPtr.Zero);         imgThumbnail.Save         (Application.StartupPath +          cstrThumbFileName);

Calling the GetThumbnailImage method and passing in the width and height of the thumbnail, along with an Image.GetThumbnailImageAbort delegate and IntPtr.Zero creates a new instance of the Image object that represents the thumbnail of your original image.

Author Note: The Image.GetThumbnailImageAbort delegate and IntPtr.Zero parameters are required even though they support a callback that is not yet used in GDI+ 1.0.

Rotating Images
Rotation transformations are often very useful, as many digital cameras and other devices that capture or scan photographic images store images in a static orientation. Depending on the content of the image and the orientation of the content, the saved format may not be suitable for viewing. By implementing a rotation function for images in your application, you can orient the images properly for display. To rotate an image, you create an Image object and load the sample image. Then use the RotateFlip method to change the orientation:

      img = System.Drawing.Image.FromFile         (strFileName);            img.RotateFlip         (RotateFlipType.Rotate90FlipNone);         img.Save(Application.StartupPath +          cstrRotateFileName);

The RotateFlip method takes a RotateFlipType parameter?an enumeration member that specifies the type of rotation/flip transformation to perform on the img object. After performing the rotation, you can save and display the image as described in the cropping section.

Changing Image Formats
Changing the file format of an image is particularly important, because many applications have limited image type support. You may need to convert the original storage format for an image to share it with other people or to use it in disparate applications.

To convert the file format conversion code, all you need is an Image object and a single method call. Consider the following code fragment:

      img = System.Drawing.Image.FromFile         (strFileName);         img.Save         (Application.StartupPath +          cstrConvertedFileName,          System.Drawing.Imaging.ImageFormat.Jpeg);

The Image.Save method takes two parameters: the file path where you want to save the converted image, and an ImageFormat object property that corresponds to the desired image format.

Drawing Text on Images
The integration of images and text is a common requirement for applications. Here’s how to apply text to the sample image file:

      const string cstrTextFileName =          "\Text_Sample.gif";                  System.Drawing.Image img;                  img = System.Drawing.Image.FromFile(strFileName);         Bitmap bmp = new Bitmap(img);                  Graphics gphText =          Graphics.FromImage(bmp);         Font f = new Font         ("Arial", 12, FontStyle.Bold | FontStyle.Italic);                  gphText.DrawString("Sample", f, Brushes.Black,          new Point(10, 15));         bmp.Save(Application.StartupPath +         cstrTextFileName);         pbImage.Image = bmp;

To draw the text, create a Bitmap instance containing the image data, and then use the Graphics.DrawString method to superimpose the string “Sample” on the image. You pass a Font object to the DrawString method. In this case, the code sets the font family to Arial, the font size to 12 (point), and the font style to bold and italic. Figure 2 shows the result of the text drawing operation.

Figure 2: The string “Sample” superimposed on the sample image.

As demonstrated by the sample application, you can use the GDI+ classes of the .NET Framework to build image manipulation functionality into your Windows forms applications, performing features including cropping, image rotation, drawing text on images and much more. While the GDI+ classes offer a huge variety of features for managing images, the code shown in this article comprises only a marginal foray into the available functionality. You can use the demonstrated techniques to develop applications that store and manage documents stored in a variety of formats, or simple easily-deployed applications that let users manipulate images.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: