How to Merge Icons?

Posted on 1998-10-12
Last Modified: 2008-03-04
If I have two Icons A and B, and I want to create a third
Icon C which comprises of B mapped over A, what is the code I need to have to do this? I'm currently using
VC++5. Mapping 2 bitmaps to an Icon will be an acceptable solution.
N.B. These are colour, NOT mono Bitmaps/Icons.
Question by:twexperts
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2

Expert Comment

ID: 1174922
Can you explain the Q a bit more

>> VC++5. Mapping 2 bitmaps to an Icon will be an acceptable solution.

If you combine 2 bitmaps into 1 with transparency, and then extract the bits this is how to do it.  Are you looking for an alternative - or are you unsure about transparency?  Info on how to do this follows.  Sorry if a bit disjointed, cutting and pasting from a previous Q that I answered (just remember to use 2 input bitmaps, and one output bitmap, then extract bits from output bitmap to make the icon)

Tell me if this is the answer you need, or if you need something else



     1. Cheat: Use an image list, you can make any chosen color in the image list transparent (I use Magenta for example)

         A. Create the image list :
         m_ilPlant.Create( IDB_PLANT, 48, 0, RGB(255,0,255) ) ;

         // m_ilPlant is the image list
         // IDB_PLANT is the bitmap resource id
         // 48 is the width of the images in the image list (remember you can put multiple images into the image list of the same width) - if only 1 image in the image list -
         make it the width of the whole thing
         // 0 is how the image list grows if you add more (I put 0 because I don't change it)
         // RGB(...etc...) is the transparency color (magenta in my case)

         B. To Draw
         m_ilPlant.Draw( &m_cdcBackdrop, 0, CPoint(x,y), ILD_NORMAL ) ;

         // where
         // m_ilPlant is the image list
         // m_cdcBackdrop is the DC to draw on
         // 0 is the image within the image list (remember multiple images allowable in a single image list)
         // CPoint(x,y) is the coordinate to draw at
         // ILD_NORMAL is a constant

     Alternative (ugly)
     1. Create memory dc and select bitmap (color) in it
     2. Create a second memory DC with a monochrome bitmap same same as original bitmap.  Create AND mask by setting background color of #1 to transparent color
     and BitBlt to this bitmap.
     3. Create a third memory dc and bitmap (color).  Create XOR mask by bitblt #1 into this with SRCCOPY and bitblting #1 into this with raster op code 0x220326
     4. Create a fourth memory dc and bitmap (color).  BitBlt from output dc into this
     5. BitBlt #2 into #4 with SRCAND raster op code.  Then BitBlt #1 into  #4 with SRCINVERT raster op code
     6. BitBlt #4 into your output dc.


Author Comment

ID: 1174923
Number 1 is a good place to expand upon, now what I want to do with this is to add the image that was created/mapped onto the DC back into the image list but also capture the background which the bitmap was place upon. (obviously having at least 1 as the third operator of the Create command).
So basically we have Image + Background = New Image in Image list.
How to do this?

Accepted Solution

Answers2000 earned 200 total points
ID: 1174924
You're using MFC right ?

Here are the steps

1. Create ImageList-1 with the "image" and and transparency color, example:

CImageList m_ilPlant ;
m_ilPlant.Create( IDB_PLANT, 48, 0, RGB(255,0,255) ) ;
// IDB_PLANT is a bitmap resource, graphic is 48 pixels wide, transparency color is magenta

2. Combine with background

(a) If background is in a bitmap
If you don't mind destroying the background simply draw the image onto the background using
m_ilPlant.Draw( pdcBackground, 0, CPoint(0,0), ILD_NORMAL ) ;

If you do ming destroying background, create another memory bitmap same size as the the background then (i) BitBlt background to memory bitmap using SRCCOPY, and then draw the image on the memory bitmap using transparency
pdcMemory->BitBlt( 0, 0, 48, 48, pdcBackground, 0, 0, SRCCOPY ) ;
m_ilPlant.Draw( pdcMemory0, CPoint(0,0), ILD_NORMAL ) ;

(b) If background is an image list, then create a memory bitmap, and draw background onto memory bitmap, then draw image
m_ilBackground.Draw( pdcMemory,0, CPoint(0,0), ILD_NORMAL ) ;
m_ilPlant.Draw( pdcMemory,0, CPoint(0,0), ILD_NORMAL ) ;

3. CImageList has an "Add" member that lets you add a CBitmap * to an image list.


I assume you know how to create these, if not, here are the main steps (assume pDC is an existing DC you wish to be compatible with)

CBitmap cbm ;
CDC cdc ;

cbm.CreateCompatibleBitmap( pDC, width, height ) ; // or use LoadBitmap to get from resources
cdc.CreateCompatibleDC( pDC ) ;
cdc.SelectObject( cbm ) ;

or non-MFC

HDC  hDC ;

hDC = CreateCompatibleDC( hdc ) ;
hBM =  CreateCompatibleBitmap( hdc, width, height ) ; // or use LoadBitmap
SelectObject( hDC, hBM ) ;

//<--- do work

//clean up:
DeleteDC( hDC ) ;
DeleteObject( hBM ) ;

Incidentally if you prefer to work with raw HBITMAPs rather than CBitmap's [I often find this easier].  CBitmap includes a nice FromHandle function which you can use to generate a temporary CBitmap for those functions that need one, e.g. Add member of CImageList

CImageList imagelist ;
imagelist.Add( CBitmap::FromHandle(hBitmap) ) ;


Author Comment

ID: 1174925
You almost had it, at least pointed me in the correct direction, so I'll award you a 'B', below is the code which I got to work correctly....
Thanks very much for your help,

  m_ImgList.Create( MAKEINTRESOURCE(IDB_FOREGRND), 32, 1, RGB(255,255,255) );  //Create the image list with the Foreground image as the first image... Transparency white!       
  CBitmap cbm;   // Create the bitmap.
  cbm.LoadBitmap(MAKEINTRESOURCE(IDB_BACKGRND)) ;  // Load in the background  resource.
  m_ImgList.Add(&cbm,RGB(255,255,255)); //Add the background to the ImageList, So that we have a copy for future reference... .
  CDC cdc;    // Create the memory DC.
  cdc.CreateCompatibleDC(NULL) ;     // Make sure it's compatable with system DC.
  CBitmap *oldbmp=cdc.SelectObject( &cbm ) ;     // Select the Background Bitmap, and store the previous one (Important).
  m_ImgList.Draw(&cdc, 0, CPoint(0,0), ILD_NORMAL );    //Draw over the background with the foreground Image.
  cdc.SelectObject(oldbmp);   //Release the modified Bitmap (Important).
  m_ImgList.Add( &cbm, RGB(0,0,0));   //Read it into the Image list, note that when we first read in the bitmap too the DC, it made the transparent color BLACK, so this is pushing it back to Transparent.
// Now draw out the images in order...
  m_ImgList.Draw(pDC, 1, CPoint(30,30), ILD_NORMAL );
  m_ImgList.Draw(pDC, 0, CPoint(30,30), ILD_NORMAL );
  m_ImgList.Draw(pDC, 2, CPoint(110,30), ILD_NORMAL );


Author Comment

ID: 1174926
Have a nice day...


Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

724 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question