Solved

Using BitBlt to change bacground of a bitmap

Posted on 1998-11-24
5
703 Views
Last Modified: 2012-05-04
[If anyone can supply sample code which works, I'll happily increase points!]

I'm using MS VC++4.2, but programming in C; writing for Win95/NT4. I want to put a bitmap on a dialog box, but change it so that the bitmap "background" is COLOR_3DFACE - and therefore the same color as the dialog box.

I've got 2 bitmaps ready; one the actual bitmap, the other a black and white mask with the pixels which are to be background color (transparent) white.

So far, my attempts have produced nothing on the dialog box; here's what I have so far...

            hdc=GetDC(hDlg);
            hdc1=CreateCompatibleDC(hdc);
            hdc2=CreateCompatibleDC(hdc);
            hdc3=CreateCompatibleDC(hdc);
            hBit1=LoadBitmap(g_hinst,MAKEINTRESOURCE( IDB_MASK));
            hBit2=LoadBitmap(g_hinst,MAKEINTRESOURCE( IDB_BITMAP));
            hBit=CreateCompatibleBitmap(hdc,12,13);
            cColor = SetBkColor(hdc1, COLOR_3DFACE);
            hOld=SelectObject(hdc1,hBit);
            hOld1=SelectObject(hdc2,hBit1);
            hOld2=SelectObject(hdc3,hBit2);
            BitBlt(hdc1,0,0,12,13,hdc2,0,0,SRCAND);
            BitBlt(hdc1,0,0,12,13,hdc3,0,0,SRCINVERT);
            SendDlgItemMessage(hDlg,IDC_DM,STM_SETIMAGE,(WPARAM) IMAGE_BITMAP,(LPARAM)hBit );
            DeleteObject(SelectObject(hdc1, hOld));
            DeleteObject(SelectObject(hdc2, hOld1));
            DeleteObject(SelectObject(hdc3, hOld2));
            DeleteDC(hdc);
            DeleteDC(hdc1);
            DeleteDC(hdc2);
            DeleteDC(hdc3);

There are probably horrendous mistakes there; can anyone spot them and show how it's really done??

Thanks!
0
Comment
Question by:McKean
  • 3
  • 2
5 Comments
 
LVL 8

Accepted Solution

by:
Answers2000 earned 300 total points
Comment Utility
About your code
1. COLOR_3DFACE is an index to a color, rather than an actual color, use GetSysColor(COLOR_3DFACE)
2. The DeleteObject's look wrong, I think you mean
DeleteObject(hOld) ; // etc


Having said all that, there are a couple of things you should know about drawing bitmaps with transparency

(a) If possible use Image Lists.  These include a transparent drawing feature.  If you need an HBITMAP as the end result do this

i. Create bitmap 1
ii. Create DC 1
iii.  Select bitmap 1 into DC 1
iv. Fill the bitmap 1 with the background color
v. Create Image List, you can specify a transparent color (e.g. Magenta - is RGB(255,0,255).  Except for this, the image list is a normal bitmap resource.
vi. Draw on the imagelist onto DC1
vii. You now have the imagelist


OR

the algorithm to do transparent bitblt is :-

              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.   Alternative use the handle to #'4 as your hBitmap


Please read the comment below too
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
Also Make sure you static control has SS_BITMAP style

Here is code for a transparent bitlbt using imagelists

 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, 0, CPoint(0,0), ILD_NORMAL );

0
 

Author Comment

by:McKean
Comment Utility
Thanks for all that! I'm not using MFC, but, having been pointed in the right direction by you, have found that the following works (where IDB_BITMAP1 contains 7 12x13 images and IDC_DM is a static SS_BITMAP control):

hImages=ImageList_Create(12,13,ILC_COLOR4 | ILC_MASK,7,0);
hBit1=LoadBitmap(g_hinst,MAKEINTRESOURCE( IDB_BITMAP1));
ImageList_AddMasked(hImages,hBit1, RGB(192,192,192));
DeleteObject(hBit1);
hdc=GetWindowDC(GetDlgItem(hDlg,IDC_DM));
ImageList_DrawEx(hImages,2,hdc,0,0,12,13,CLR_NONE,CLR_NONE, ILD_TRANSPARENT);
ReleaseDC(GetDlgItem(hDlg,IDC_DM),hdc);

The only problem is that it won't work under WM_INITDIALOG, presumably because the dialog hasn't yet been displayed and the DC not valid. Is there a way round that, because I want the image displayed on the dialog on creation, and at the moment nothing appears - though if I include the above code under a clicked event, for example, the bitmap does appear on click.

0
 

Author Comment

by:McKean
Comment Utility
Thanks for all that! I'm not using MFC, but, having been pointed in the right direction by you, have found that the following works (where IDB_BITMAP1 contains 7 12x13 images and IDC_DM is a static SS_BITMAP control):

hImages=ImageList_Create(12,13,ILC_COLOR4 | ILC_MASK,7,0);
hBit1=LoadBitmap(g_hinst,MAKEINTRESOURCE( IDB_BITMAP1));
ImageList_AddMasked(hImages,hBit1, RGB(192,192,192));
DeleteObject(hBit1);
hdc=GetWindowDC(GetDlgItem(hDlg,IDC_DM));
ImageList_DrawEx(hImages,2,hdc,0,0,12,13,CLR_NONE,CLR_NONE, ILD_TRANSPARENT);
ReleaseDC(GetDlgItem(hDlg,IDC_DM),hdc);

The only problem is that it won't work under WM_INITDIALOG, presumably because the dialog hasn't yet been displayed and the DC not valid. Is there a way round that, because I want the image displayed on the dialog on creation, and at the moment nothing appears - though if I include the above code under a clicked event, for example, the bitmap does appear on click.

0
 

Author Comment

by:McKean
Comment Utility
Got it working now - thanks for advice which pointed me in right direction!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

763 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

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now