Re: ImageList_Draw and icons with alpha channel
- From: "Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx>
- Date: Thu, 27 Oct 2005 10:11:31 -0400
The AND mask represents the "Alpha Channel".
Where the pixel is marked as "White", the pixel in the final
destination bitmap will be replaced by the background color
after application of the XOR and AND masks.
Using masks works for all bit depths and allows you to
create icons, cursors or use bitmaps that can be TransBlt
accross the screen. You don't have the option of fine
tuning the alpha channel for degree of opacity on a per
pixel basis.
If you want to define the degree of opacity
on a per pixel basis, you only have one option.
For the 32bpp case only, you may create the masks as follows:
1) Use a BITMAPV5HEADER and CreateDIBSection
to create an alpha channel canvas to draw your icon and text.
2) Use CreateBitmap to create an AND mask. You leave this
mask alone(i.e., don't set the bits on or off )
3) Use the pointer to the DIBSECTION bits to create the "AND"
mask. You use the same algorithm but operate on the alpha
channel only. You can refine the degree of opacity from 0 to 255
on a per pixel basis.
4) When your done, premultiply the alpha channel against the individual
colors.
5) Use the rest of your code to add the bitmap masks.
Keep in mind that normal Windows bitmaps are BI_RGB where
each pixel is formatted as 0x00BBGGRR. The alpha channel is
ignored.
An Alpha channel bitmap created by a BITMAPV5HEADER is
formatted as 0xAARRGGBB. If you premultiply the alpha channel
against the individual colors, you can ensure yourself that the
alpha channel will be preserved using Windows GDI calls.
"Timo Kunze" <TKunze71216@xxxxxx> wrote in message
news:%235CZSZo2FHA.2364@xxxxxxxxxxxxxxxxxxxxxxx
> We're getting closer. :)
> With my (better: your) current code, the drag image contains the icon
> and the text (with correct colors) - on Windows XP SP2 as well as on
> Windows 2003 SP1. This is the first time I got this working with
> ILC_COLOR32. Looks like using CreateDIBSection is the key.
> However, the per-pixel alpha transparency still gets lost. I think it's
> because the AND mask tells GDI that these pixels are opaque and actually
> it should tell GDI that they're transparent, am I right? Then we'd need
> a way to read out each pixel's alpha channel in the for loops and set
> the AND mask's pixel to white if it is different than 255. Shouldn't be
> that difficult, but I'm too tired to try it right now.
>
> Here's the code I'm currently using:
>
> // create a memory DC
> WTL::CDC memoryDC;
> memoryDC.CreateCompatibleDC();
>
> // create a 32bpp DIB
> WTL::CBitmap dibBitmap32bpp;
> BITMAPINFO bitmapInfo = {0};
> bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
> bitmapInfo.bmiHeader.biWidth = 90;
> bitmapInfo.bmiHeader.biHeight = 50;
> bitmapInfo.bmiHeader.biPlanes = 1;
> bitmapInfo.bmiHeader.biBitCount = 32;
> bitmapInfo.bmiHeader.biCompression = BI_RGB;
> dibBitmap32bpp.CreateDIBSection(memoryDC, &bitmapInfo, DIB_RGB_COLORS,
> NULL, NULL, 0);
>
> // setup the memory DC
> WTL::CFontHandle font = (HFONT) SendMessage(WM_GETFONT, 0, 0);
> HFONT hPreviousFont = NULL;
> if(!font.IsNull()) {
> hPreviousFont = memoryDC.SelectFont(font);
> }
> HBITMAP hPreviousBitmap1 = memoryDC.SelectBitmap(dibBitmap32bpp);
> memoryDC.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
> memoryDC.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
>
> /* Fill the bitmap's background with an ugly magenta. Magenta pixels
> will become transparent. */
> COLORREF transparentColor = RGB(255, 0, 255);
> WTL::CBrush backgroundBrush;
> backgroundBrush.CreateSolidBrush(transparentColor);
> memoryDC.FillRect(WTL::CRect(0, 0, 90, 50), backgroundBrush);
>
> // draw content
> HICON hIcon = ::ImageList_ExtractIcon(NULL, hSourceImageList,
> item.iImage);
> memoryDC.DrawIcon(0, 0, hIcon);
> ::DestroyIcon(hIcon);
> memoryDC.DrawText(_T("Hello"), 5, WTL::CRect(40, 10, 80, 30),
> DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
>
> // create the masks that together build the drag image
> WTL::CBitmap xorMask;
> xorMask.CreateCompatibleBitmap(memoryDC, 90, 50);
> WTL::CDC xorMaskDC;
> xorMaskDC.CreateCompatibleDC();
> HBITMAP hPreviousBitmap2 = xorMaskDC.SelectBitmap(xorMask);
>
> WTL::CBitmap andMask;
> andMask.CreateBitmap(90, 50, 1, 1, NULL);
> WTL::CDC andMaskDC;
> andMaskDC.CreateCompatibleDC();
> HBITMAP hPreviousBitmap3 = andMaskDC.SelectBitmap(andMask);
>
> // draw the masks pixel by pixel
> for(DWORD x = 0; x < 90; x++) {
> for(DWORD y = 0; y < 50; y++) {
> if(memoryDC.GetPixel(x, y) == transparentColor) {
> andMaskDC.SetPixel(x, y, RGB(255, 255, 255));
> xorMaskDC.SetPixelV(x, y, RGB(0, 0, 0));
> } else {
> andMaskDC.SetPixel(x, y, RGB(0, 0, 0));
> xorMaskDC.SetPixel(x, y, memoryDC.GetPixel(x, y));
> }
> }
> }
> ::GdiFlush();
>
> // clean up
> memoryDC.SelectFont(hPreviousFont);
> memoryDC.SelectBitmap(hPreviousBitmap1);
> xorMaskDC.SelectBitmap(hPreviousBitmap2);
> andMaskDC.SelectBitmap(hPreviousBitmap3);
>
> // create the imagelist containing our drag image
> HIMAGELIST hDragImageList = ::ImageList_Create(90, 50, ILC_COLOR32 |
> ILC_MASK, 1, 0);
> ::ImageList_SetBkColor(hDragImageList, CLR_NONE);
> // add the drag image
> ::ImageList_Add(hDragImageList, xorMask, andMask);
>
> // ImageList_BeginDrag will be called with hDragImageList
>
> Timo
> --
> www.TimoSoft-Software.de - the home of ExplorerTreeView
> Stop software patents!
.
- Follow-Ups:
- Re: ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- Re: ImageList_Draw and icons with alpha channel
- References:
- ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- Re: ImageList_Draw and icons with alpha channel
- From: Michael Phillips, Jr.
- Re: ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- Re: ImageList_Draw and icons with alpha channel
- From: Michael Phillips, Jr.
- Re: ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- Re: ImageList_Draw and icons with alpha channel
- From: Michael Phillips, Jr.
- Re: ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- Re: ImageList_Draw and icons with alpha channel
- From: Michael Phillips, Jr.
- Re: ImageList_Draw and icons with alpha channel
- From: Michael Phillips, Jr.
- Re: ImageList_Draw and icons with alpha channel
- From: Timo Kunze
- ImageList_Draw and icons with alpha channel
- Prev by Date: RE: metafile, selectobject, index
- Next by Date: Re: ENHMETAHEADER - file.emf - handle & palette tables
- Previous by thread: Re: ImageList_Draw and icons with alpha channel
- Next by thread: Re: ImageList_Draw and icons with alpha channel
- Index(es):
Relevant Pages
|