?
Solved

Transparent Bitmap on a Button

Posted on 2011-10-27
10
Medium Priority
?
1,449 Views
Last Modified: 2013-11-20
There are several issues about this subject, to draw the bitmap + mask on a DC.

I need to place it on a button via SetBitmap.

I'm using on VC 6.0 on Windows XP.

I have loaded the bitmap using 'LoadImage', created the mask with 'CreateBitmapMask', now I need to 'merge' them together on a new bitmap. to place it on SetBitMap

The bitmap are 24 bit bmp, converted from png witch result havin a black backgroud.

How can i do this?

Vitor Sarabando
0
Comment
Question by:vss-pt
  • 3
  • 3
  • 2
  • +1
10 Comments
 
LVL 35

Expert Comment

by:sarabande
ID: 37043125
you can transform the bitmap into the destination dc by calling TransparentBlt where you tell which color should be used for 'transparency'. if your image now has a black background you should use black color RGB(0, 0, 0).

Sara
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 37043724
Hi vss-pt,

as long as you don't draw the button yourself (i.e. by using a owner-draw button) IMO there's no chance to get a bitmap drawn transparent with using 'CButton::SetBitmap'.

I would suggest to create an icon with transparency from the bitmap and the mask and use 'CButton::SetIcon'.

To create the icon you can use 'CreateIconIndirect' and pass the bitmap and mask in the passed ICONINFO.

Hope that helps,

ZOPPO
0
 

Author Comment

by:vss-pt
ID: 37045383
Hi Sara,

II have tried this but still no tranaparent areas.

HBITMAP hBmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
             MAKEINTRESOURCE(nBitmap),
             IMAGE_BITMAP,
             nCx,
             nCy,                            
                            LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS|LR_SHARED|LR_DEFAULTSIZE);

HDC hdcSrc = CreateCompatibleDC(NULL);
HDC hdcDst = CreateCompatibleDC(NULL);
SelectObject(hdcSrc, hBmp);
HBITMAP hbmOld, hbmOld2, hbmNew;
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
hbmOld = (HBITMAP) SelectObject(hdcSrc, hBmp);
hbmNew = CreateBitmap( bm.bmWidth, bm.bmHeight, bm.bmPlanes,bm.bmBitsPixel,NULL);
hbmOld2 = (HBITMAP)SelectObject(hdcDst, hbmNew);
TransparentBlt(hdcDst, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc,0, 0, bm.bmWidth, bm.bmHeight, RGB(0,0,0)));

SelectObject(hdcSrc, hbmOld);
DeleteDC(hdcSrc);
DeleteDC(hdcDst);
pBtn->SetBitmap( hbmNew);

The best solition I have acheived is the mask created with "'CreateBitmapMask'" that is the perfect shape of the drawing, but still is all black. I wonder if there is a way to "AND" the two bitmaps?

Vitor
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 35

Expert Comment

by:sarabande
ID: 37050286
you should check the bitmap rgb values whether the background color (the one you want to have transparent) really is black.

you should select the bitmap into the (compatible) hdcSrc.

but the destination dc should be the real screen dc and not a compatible dc.

before you delete a dc where a new bitmap was selected in, you should "unselect" the new bitmap by selecting the old bitmap into dc and call DleteObject for the bitmap.

Sara
0
 
LVL 12

Expert Comment

by:satsumo
ID: 37063408
The button's parent window needs to have WS_CLIPCHILDREN turned off, it is on by default.  Having this set means that the parent window doesn't paint anything behind the button.  Though you could try drawing the background for the button yourself, that removes the point of doing transparency.  Downside is that it clearing WS_CLIPCHILDREN will paint behind all controls.

The button needs to be drawing itself.  In some APIs that means setting the BS_OWNERDRAW style, in others you just implement your own paint function.

If you have a mask bitmap and a color bitmap you can combine them with BitBlt and different ROP codes for each bitmap.  Normally that would be SRCAND for the mask and SRCPAINT for the color.

You could use AlphaBlend for the same effect, that requires getting the transparency into the alpha of the bitmap and Windows is entirely ambiguous about how you do that.  The simplest was is probably to copy the alpha bits in code.

GDI was never designed for dealing with alpha channels, a BITMAPINFOHEADER contains no alpha information.  If you set the BitCount to 32 it's supposed to ignore the alpha bits, even though AlphaBlend uses those bits.
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 37075067
@vss-pt: Did you try to create and use an icon? IMO you won't need to implement anything else like drawing the bitmap to the button yourself ... just set the button's style 'BS_ICON' and use CButton::SetIcon should be enough.

ZOPPO
0
 

Author Comment

by:vss-pt
ID: 37075357
@Zoppo: How do I convert the png or bmp to a icon? Cam i Mantail the color deepth?
0
 
LVL 12

Expert Comment

by:satsumo
ID: 37075457
You can load up the icon editor and just paste the image into it from Photoshop, Paint or from a bitmap in the bitmap editor.  Though VC isn't always friendly about the color palette when paste into an icon.

AFAIK, icons can have up to 256 colors, though Zoppo might know better.  I don't know whether Vista or 7 allow more than 256 colors, but its enough for the vast majority of purposes.  Icons are usually small, simple images.  PNG and BMP both have a 256 color mode, you can index them in Photoshop.  You may have to index to the Windows System Palette.

The alpha part of an icon is one bit, they can't have soft edges or semi-transparent parts (again Zoppo might know different).  Either 100% transparent or 100% opaque.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 37075571
the vc6 icon/bitmap editor in resource editor has a color for transparancy.

i also think one could edit icons 32x32 with 256 colors.

you could try to paste a bitmap to that editor but probably you need to have make same size before in a paint program like mspaint. then use the editor to set transparant pixels.

Sara
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 1000 total points
ID: 37075589
Well, as told above, you can use CreateIconIndirect - I think you already have the bitmap and the mask since you wrote I have loaded the bitmap using 'LoadImage', created the mask with 'CreateBitmapMask. AFAIK icons even support 24 (RGB) and 32 (RGBA) - take a look at following link, you'll find Windows XP adds support for 32-bit color (16.7 million colors plus alpha channel transparency) icon images, thus allowing semitransparent areas like shadows, anti-aliasing, and glass-like shapes to be drawn in an icon.: http://en.wikipedia.org/wiki/ICO_%28file_format%29

ZOPPO
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Suggested Courses

850 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