Click here to Skip to main content
Click here to Skip to main content

Replacing Part of an Existing Bitmap

, 28 Jul 2006
Rate this:
Please Sign up or sign in to vote.
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)

About the Author

John Simmons / outlaw programmer
Software Developer (Senior)
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! PinmemberMaurog_Dark12-Apr-07 3:04 
GeneralGetting Problem in PNG Format Pinmemberchintan.desai27-Nov-06 19:21 
GeneralVery gud Topic Pinmemberchintan.desai24-Nov-06 23:24 
GeneralSmall suggestion PinmemberChris Richardson28-Jul-06 11:14 
GeneralRe: Small suggestion [modified] PinmemberJohn Simmons / outlaw programmer28-Jul-06 11:59 
GeneralRe: Small suggestion PinmemberMike Dimmick29-Jul-06 1:28 
GeneralRe: Small suggestion PinmemberJohn Simmons / outlaw programmer31-Jul-06 2:14 
QuestionIsn't that what ImageList_Replace's for? PinmemberIvo Beltchev28-Jul-06 9:44 
AnswerRe: Isn't that what ImageList_Replace's for? [modified] PinmemberJohn Simmons / outlaw programmer28-Jul-06 9:56 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 28 Jul 2006
Article Copyright 2006 by John Simmons / outlaw programmer
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid