Click here to Skip to main content
15,867,594 members
Articles / Desktop Programming / MFC
Article

Replacing Part of an Existing Bitmap

Rate me:
Please Sign up or sign in to vote.
3.77/5 (32 votes)
28 Jul 2006CPOL3 min read 55.7K   540   29   9
Copy a bitmap over a portion of another bitmap

Sample Image - bitmaptest_screenshot.png

Introduction

Every once in a while, you need the capability to do something in code that requires a an amount of research that is usually disproportionate to the final number of lines required to implement the code. Manipulating bitmaps is one of those things. For most of us, doing GDI stuff is one of the most distasteful (and mysterious) coding tasks we can imagine.

In the course our current development efforts, I decided that I wanted to dynamically change the contents of an CImageList. By "dynamically", I mean building the bitmaps and then replacing a given image in an existing image list. I know - insaity, pure insanity. Well, no great idea goes unpunished, and mine was no exception. After figuring out how to do it, circumstances prevented me from actually using the code. However, that doesn't mean you (the audience) can't benefit from my experience.

The core idea here was to take an existing bitmap, and replace part of that bitmap with another (smaller?) bitmap, and this is what this article describes. What you do with the resulting bitmap is limited only by your imagination. The following is a description of the function in the demo app that does all of the related work.

How It's Done - Partially Replacing an Existing Bitmap

First, we have to establish some parameters. Since the demo works with images whose sizes are static and already known, we have it pretty simple. The width and height of our small bitmaps are 20x20. The "target" bitmap is 60x20.

int nWidth       = 20;
int nHeight      = 20;
int nTargetWidth = 60;

Next, we establish where we want to copy the selected source bitmap on the target bitmap.

int nCoordX      = m_nSection * 20;
int nCoordY      = 0;

Here, we call a dialog box function to retrieve the appropriate (and already loaded) bitmap.

CBitmap* pBmpSource = GetSourceBitmap(nImgNumb);

Then, we want to define and initialize some necessary objects. Since we'll be working with device contexts, we need a CBitmap pointer for both the source and target bitmaps, as well as device context objects.

CBitmap* pOldTargetBmp = NULL;
CBitmap* pOldSourceBmp = NULL;
CDC      targetDC;
CDC      sourceDC;
CDC*     pDC = this->GetDC();

Now comes the interesting part. We need to create a device context on which we can render the bitmaps.

targetDC.CreateCompatibleDC(pDC);
sourceDC.CreateCompatibleDC(pDC);

Then, we select the target bitmap into the target DC, and the source bitmap into the source DC.

pOldTargetBmp = targetDC.SelectObject(&m_BmpTarget);
pOldSourceBmp = sourceDC.SelectObject(pBmpSource);

This is where the magic occurs. We us BitBlt to copy the contents of the source DC into the target DC at the specified coordinates. Remember, we set values for the first four parameters at the top of the function.

targetDC.BitBlt(nCoordX, nCoordY, nTargetWidth, nHeight, &sourceDC,
                0, 0, SRCCOPY);

Now that we've done everything we need to do with the device contexts, we can free up the resources and clean up.

sourceDC.SelectObject(pOldSourceBmp);
targetDC.SelectObject(pOldTargetBmp);

sourceDC.DeleteDC();
targetDC.DeleteDC();

ReleaseDC(pDC);

The last step is to set the bitmap control on the dialog to use our new bitmap.

m_ctrlTargetImage.SetBitmap(HBITMAP(m_BmpTarget));

And there you have it - copying a bitmap to another bitmap in leas than 20 lines of code (not counting the code that got us here, of course).

If you have questions, I'll do my best to answer them, but I'm not the best person to ask about the esoteric bitmap mangling theory. You might be better off asking questions in the MFC/VC++ forum here on CodeProject.

Legacy Compilers

The demo project was created with VS2005, but you should be able to copy/paste the desired code directly into any project using VC5 through VS2003 without any problems. If you do have problems, you should be perfectly capable of figuring out how to fix them. Afterall, you're a programmer, right?

Credits

Many thanks to PJ Arends and Christian Graus for their assistance in getting the code above to work.

I used PJ's bitmap debugger utility to make sure everything was working as it should.

Another honorable mention goes to Chris Richardson for pointing out an omission where releasing a DC is concerned.

Updates

  • 07/31/2006 - Corrected some spelling errors, and updated the code and article body to reflect a missing call to ReleaseDC.
  • 07/28/2006 - Original Article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
GeneralWorked like a charm! Pin
Maurog_Dark12-Apr-07 3:04
Maurog_Dark12-Apr-07 3:04 
I needed the exact opposite of what you did here - splitting one huge bitmap into many small ones, but the principle was the same. The MFC help wasn't really helpful for someone like me who never really worked with CBitmaps before. This article was. Two thumbs up!
GeneralGetting Problem in PNG Format Pin
Chintan.Desai27-Nov-06 19:21
Chintan.Desai27-Nov-06 19:21 
GeneralVery gud Topic Pin
Chintan.Desai24-Nov-06 23:24
Chintan.Desai24-Nov-06 23:24 
GeneralSmall suggestion Pin
Chris Richardson28-Jul-06 11:14
Chris Richardson28-Jul-06 11:14 
GeneralRe: Small suggestion [modified] Pin
#realJSOP28-Jul-06 11:59
mve#realJSOP28-Jul-06 11:59 
GeneralRe: Small suggestion Pin
Mike Dimmick29-Jul-06 1:28
Mike Dimmick29-Jul-06 1:28 
GeneralRe: Small suggestion Pin
#realJSOP31-Jul-06 2:14
mve#realJSOP31-Jul-06 2:14 
QuestionIsn't that what ImageList_Replace's for? Pin
Ivo Beltchev28-Jul-06 9:44
Ivo Beltchev28-Jul-06 9:44 
AnswerRe: Isn't that what ImageList_Replace's for? [modified] Pin
#realJSOP28-Jul-06 9:56
mve#realJSOP28-Jul-06 9:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.