Using the ATL CImage Class

From Kate Gregory’s Codeguru column, “Using Visual C++ .NET“.

–>

Visual Studio.NET introduced Managed C++, but that wasn’t the only thing that was new in it. A number of interesting changes to MFC and ATL make life simpler for those who are working in unmanaged C++. In this column I’ll introduce you to the CImage class, which has been added to ATL and adds enhanced bitmap support. Figure 1 shows a simple application that displays and converts images.

This is an ordinary MFC dialog application. I added a textbox, two buttons captioned “Load” and “Save As JPG,” and a picture control. Then I deleted the Cancel button, and changed the caption (but not the ID) of the OK button to Done.

Figure 1 – Displaying and converting images.

Because this is a dialog application, AppWizard created a dialog class for me. I added variables by right-clicking on the surface of the dialog in the resource editor and choosing Add Variable. (ClassWizard is gone in this version of Visual Studio, so you have to learn how to get to the Add Member Variable Wizard dialog.) Here’s a summary of the variables I added, all private:

Control ID  Variable Name   Control/Value   Variable Type  
IDC_PICTURE m_picture Control CStatic
IDC_FILENAME m_filename Value CString
IDC_SAVE m_savebutton Control Cbutton

I used the Properties Window to disable the “Save As JPG” button by default (there’s code later to enable it.) I also changed the Type of the picture control to Bitmap. And finally, I edited the header file for the dialog class, adding a member variable called m_image of type CImage. At the top of the header file go these two #include statements:

#include <afxstr.h>
#include <atlimage.h>

It’s important that these include statements appear in this order. This is really the only indication you have that CImage is an ATL class rather than an MFC class.

Here’s how simple it is to load a GIF or JPG from the hard drive into a CImage object and show it in the picture control:

void CImageDlg::OnBnClickedLoad()
{
    UpdateData(TRUE);
    if (m_filename == "")
        m_filename = "Please enter a file name first";
    else
    {
        if (m_image.Load(m_filename) == S_OK)
        {
            m_picture.SetBitmap((HBITMAP)m_image);
            m_picture.Invalidate();
            m_savebutton.EnableWindow(TRUE);
        }
        else
        {
            AfxMessageBox("File not found or invalid format");
        }
    }
    UpdateData(FALSE);
}

I even have room for a little error checking! I also enable the “Save As JPG” button once an image is successfully loaded. If you’re adapting this code for your own use, don’t skip the call to Invalidate() – it ensures the picture control will redraw itself.

What about converting a GIF to a JPEG? All you have to do is save the image. The format is implied by the file name. Here’s how to do it:

void CImageDlg::OnBnClickedSave()
{
    CString filename = m_filename.Left(
        m_filename.Find('.')) + ".JPG";
    m_image.Save(filename);
}

Two lines of code! How hard is that?

What else can you do with a CImage object? Well, you don’t have to load one from an existing picture file. You can draw on it by creating a device context associated with the bitmap inside the CImage:

CDC* pDC = CDC::FromHandle(image.GetDC());

Be sure to call ReleaseDC afterwards.

CImage supports transparency, alpha blends and a variety of other cool effects, on reasonably recent versions of Windows. If you are writing unmanaged (Classic C++) code that needs to work with images, look into CImage. While it is part of ATL, you can’t tell, can you? There’s no sign of templates or anything tricky at all. And in my next column, I’ll show you the Managed C++ equivalent for this application.

About the Author

Kate Gregory is a founding partner of Gregory Consulting Limited (www.gregcons.com). In January 2002, she was appointed MSDN Regional Director for Toronto, Canada. Her experience with C++ stretches back to before Visual C++ existed. She is a well-known speaker and lecturer at colleges and Microsoft events on subjects such as .NET, Visual Studio, XML, UML, C++, Java, and the Internet. Kate and her colleagues at Gregory Consulting specialize in combining software develoment with Web site development to create active sites. They build quality custom and off-the-shelf software components for Web pages and other applications. Kate is the author of numerous books for Que, including Special Edition Using Visual C++ .NET.

# # #

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read