Using the ATL CImage Class
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.
# # #
Comments
source
Posted by googoohead on 04/23/2010 03:35pmCan you please email me the source code as well. Thank you.
ReplyPlease help
Posted by predoni on 05/06/2007 09:20amCan you please provide the entire source code.
Re:Source
Posted by namcs on 03/24/2008 03:30amHi Kevin, Could you please send me one copy of your source code? I've tried to follow the instruction but still can't make it works. Thankyou in advance.
ReplySource
Posted by ckweius on 08/20/2007 06:42amHi let me know your email, I will send you the similar source.
ReplyMember types? Class definition?
Posted by Mr. X on 07/01/2005 05:51amI like the conciseness of this article but the sample should include the class definition, as the author's naming convention does not show it.
Replycan this atl exe work in 95,98 etc.
Posted by fermisoft on 12/08/2004 12:49amhi i couldn't found thie atlimage header file in VStudio 6. Will this code work in 95,98 etc..
Reply