Manipulating Images in GDI+


This article has been excerpted from book "Graphics Programming with GDI+".

In this article we will manipulate images and view the following topics:

  • Creating image thumbnails
  • Rotating
  • Flipping and zooming in and out (magnifying and demagnifying) image

Creating a Thumbnail of an Image

A thumbnail is a small representation of an image. The Image class provides a method called GetThumbnailImage, which is used to create a thumbnail. This method's first two parameters are the width and height of the thumbnail image. The third parameter is Image.GetThumbnailImageAbort, which is not used in GDI+ version 1.0 but must be passed for compatibility. The fourth parameter must be of type IntPtr.Zero. This parameter is not used in the current version. If both the width and height parameter are 0, GDI+ will return the embedded thumbnail if there is one in the image; otherwise a system-defined size is used. For the most JPEG image from digital cameras, it is better to pass both zeros in for both parameters to get the embedded thumbnail.

To test the thumbnail code, we add a menu named Options to the MainMenu control, as well as a Create Thumbnail menu item. We add Create Thumbnail as a submenu item or on a button click event handler, as Listing 7.6 shows. We create an Image.GetThumbnailImageAbout parameter, and then we call GetThumbnailImage with one-fourth the width and height of the original size, followed by the DrawImage method.

LISTING 7.6: Creating and drawing a thumbnail image

        private void ThumbnailMenu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                //Callback
                Image.GetThumbnailImageAbort tnCallBack = new Image.GetThumbnailImageAbort(tnCallbackMethod);

                //Get the thumbnail image
                Image thumbNailImage = curImage.GetThumbnailImage (100, 100, tnCallBack, IntPtr.Zero);

                //Create a Graphics object
                Graphics tmpg = this.CreateGraphics();
                 tmpg.Clear(this.BackColor);

                //Draw thumbnail image
                 tmpg.DrawImage(thumbNailImage, 40, 20);

                //Dispose of Graphics object
                 tmpg.Dispose();
            }
        }

        //Must be called, but not used
        public bool tnCallbackMethod()
        {
            return false;
        }

Now we run the application and open Neel01.jpg. If we click the Create Thumbnail menu item, the new thumbnail image looks like Figure 7.7

Rotation and Flipping Images

Rotating and flipping are common operations in many imaging programs. Rotation rotates an image at an angle that is a multiple of 90. Flipping reflects an image on an axis.

The RotateFlip method allows us to rotate and flip images. The value of RotateFlip is of type RotateFlipType enumeration, which defines the direction of rotation and flipping. The members of the RotateFlipType enumeration (listed in Table 7.5) are easy to understand.

Figure 7.7.jpg

FIGURE 7.7: A thumbnail image

To rotate and/or flip an image, call RotateFlip and pass in any of the values in Table 7.5. The following code snippet show different rotation and flip options.

  • Rotating 90 degrees:
    curImageRotateFlip (RotateFlipType.Rotate90FlipNone);
  • Rotating 180 degrees:
    curImageRotateFlip (RotateFlipType.Rotate180FlipNone);
  • Rotating 270 degrees:
    curImageRotateFlip (RotateFlipType.Rotate270FlipNone);
  • Flipping on the x-axis only, with no rotation:
    curImageRotateFlip (RotateFlipType.RotateNoneFlipX);
  • Flipping on the y-axis only, with no rotation:
    curImageRotateFlip (RotateFlipType.RotateNoneFlipY);
  • Flipping on the x- and y-axis only, with no rotation:
    curImageRotateFlip (RotateFlipType.RotateNoneFlipXY);
  • Rotating 180 degrees and flipping on the x-axis
    curImageRotateFlip (RotateFlipType.Rotate180FlipX);

Adding Rotate and Clip Options to the Image Viewer

Now let's add rotate and flip options to the ImageViewer application.

We add four submenus to the Options menu- Rotate, Flip, Fit, and Zoom. We will cover the Rotate and Flip options in this section, and Fit and Zoom in Section 7.3.4 and 7.3.5, respectively.

TABLE 7.5: RotateFlipType members

Members

Description

Rotate180FlipNone

180-degree rotation without flipping

Rotate180FlipX

180-degree rotation with a horizontal flip

Rotate180FlipXY

180-degree rotation with a horizontal and vertical flips

Rotate180FlipY

180-degree rotation with a vertical flip

Rotate270FlipNone

270-degree rotation without flipping

Rotate270FlipX

270-degree rotation with a horizontal flip

Rotate270FlipXY

270-degree rotation with a horizontal and vertical flips

Rotate270FlipY

270-degree rotation with a vertical flip

Rotate90FlipNone

90-degree rotation without flipping

Rotate90FlipX

90-degree rotation with a horizontal flip

Rotate90FlipXY

90-degree rotation with a horizontal and vertical flip

Rotate90FlipY

90-degree rotation with a vertical flip

RotateNoneFlipNone

No rotation and no flipping

RotateNoneFlipX

No rotation, with a horizontal flip

RotateNoneFlipXY

No rotation, with horizontal and vertical flips

RotateNoneFlipY

No rotation, with a vertical flip

We add three items to the Rotate submenu: 90, 180 and 270 (see Figure 7.8). These items rotate an image 90, 180, and 270 degrees, respectively. You can add as many items as you want. You can even allow users to enter an arbitrary angle.
  
Now we add three items to the Flip submenu: FlipX, FlipY, and FlipXY (see Figure 7.9). These items flip an image about the x-, y-, and xy-axes, respectively. you can add more items if you wish.


Within our program we give the menu items meaningful names. For example, the 90, 180, and 270 menu items are represented by Rotate90Menu, Rotate180Menu, and Rotate270Menu, respectively. And we use FlipXMenu, FlipYMenu, and FlipXYMenu to represent the FlipX, FlipY, and FlipXY menu items, respectively.

The next step is to write code for the menu item event handlers. To add them, we simply double-click on the menu items. The code for the Rotate menu items is given in Listing 7.7. We check whether the Image object has been created and then call RotateFlip with the appropriate value. We also call Invalidate to redraw the image with new settings.

Figure 7.8.jpg

FIGURE 7.8: Rotate menu items

Figure 7.9.jpg

FIGURE 7.9: Flip menu items

        //Rotate 90 degrees
        private void Rotate90Menu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
                Invalidate();
            }
        }

        //Rotate 180 degrees
        private void Rotate180Menu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
                Invalidate();
            }
        }

        //Rotate 270 degrees
        private void Rotate270Menu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
                Invalidate();
            }
        }

Now let's run and test the application. We open an image, and its looks like Figure 7.10.

Select Rotate | 90 generates the image shown in Figure 7.11.
Select Rotate | 180 generates the image shown in Figure 7.12.
Select Rotate | 270 generates the image shown in Figure 7.13.

We also add code for the Flip menu item click event handlers, as shown in Listing 7.8. We simply call RotateFlip with an appropriate value.

LISTING 7.8: Flip menu item event handlers

        //Flip X
        private void FlipXMenu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
                Invalidate();
            }
        }

        //Flip Y
        private void FlipYMenu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
                Invalidate();
            }
        }

        //Flip X and Y both
        private void FlipXYMenu_Click(object sender, System.EventArgs e)
        {
            if (curImage != null)
            {
                curImage.RotateFlip(RotateFlipType.RotateNoneFlipXY);
                Invalidate();
            }
        }

Figure-7.10.jpg

FIGURE 7.10: An image with default settings

Figure 7.11.jpg

FIGURE 7.11: The image of Figure 7.10, rotate 90 degrees

Figure 7.12.jpg

FIGURE 7.12: The image of Figure 7.10, rotate 180 degrees

Figure 7.13.jpg

FIGURE 7.13: The image of Figure 7.10, rotate 270 degrees

Figure 7.14.jpg

FIGURE 7.14: The image of Figure 7.10, flipped in the x-direction

Now, if we flip the image shown in Figure 7.10, we can see the difference. 

The FlipX option generates the image shown in Figure 7.14.
The FlipY option generates the image shown in Figure 7.15.
The FlipXY option generates the image shown in Figure 7.16.

Conclusion

Hope the article would have helped you in understanding manipulating Images in GDI+. Read other articles on GDI+ on the website.

bookGDI.jpg
This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows.


Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.