Introduction
I finally managed to get transparent drawing working and made a few routines that makes it a snap. I adapted this code from an example Chris Becke's Bitmap Basics - A GDI tutorial.
The situation
I have a master picture with lots of images in it, the transparent areas are all in purple. At runtime I pick parts of this picture and BitBlt
it on the screen while preserving the transparency.
Or maybe you have a bitmap that you wish to show transparently, just set the transparent areas to a unique color and use the routines below.
First the routines, at the end an example that puts it all together.
BOOL CMyDlg::LoadFileBitmap(CBitmap* pBmp, LPCTSTR szFilename)
{
?? pBmp->DeleteObject();
?? return pBmp->Attach(LoadImage(NULL, szFilename, IMAGE_BITMAP, 0, 0,
????????????????????? LR_LOADFROMFILE | LR_DEFAULTSIZE));
}
void CMyDlg::PrepareMask( CBitmap* pBmpSource,
????????????????????????? CBitmap* pBmpMask,
????????????????????????? COLORREF clrpTransColor, int iTransPixelX,????? int iTransPixelY??????
??????????????????????? )
{
?? BITMAP bm;
??
?? pBmpSource->GetObject(sizeof(BITMAP), &bm);
??
?? pBmpMask->DeleteObject();
?? pBmpMask->CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL);
??
?? CDC hdcSrc, hdcDst;
?? hdcSrc.CreateCompatibleDC(NULL);
?? hdcDst.CreateCompatibleDC(NULL);
??
?? CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(pBmpSource);
?? CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(pBmpMask);
??
?? COLORREF clrTrans;
?? if (clrpTransColor == NULL)
?? {
?????
????? clrTrans = hdcSrc.GetPixel(iTransPixelX, iTransPixelY);
?? }
?? else
?? {
????? clrTrans = clrpTransColor;
?? }
??
?? COLORREF clrSaveBk? = hdcSrc.SetBkColor(clrTrans);
??
?? hdcDst.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcSrc,0,0,SRCCOPY);
??
?? COLORREF clrSaveDstText = hdcSrc.SetTextColor(RGB(255,255,255));
?? hdcSrc.SetBkColor(RGB(0,0,0));
?? hdcSrc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcDst,0,0,SRCAND);
??
?? hdcDst.SetTextColor(clrSaveDstText);
?? hdcSrc.SetBkColor(clrSaveBk);
?? hdcSrc.SelectObject(hbmSrcT);
?? hdcDst.SelectObject(hbmDstT);
?? hdcSrc.DeleteDC();
?? hdcDst.DeleteDC();
}
void CMyDlg::DrawTransparentBitmap(CMemDC* pDC,
?????????????????????????????????? int xStart,? int yStart,
?????????????????????????????????? int wWidth,? int wHeight,
?????????????????????????????????? CDC* pTmpDC,
?????????????????????????????????? int xSource, ????????????????????????????????????int ySource?
{
??
?? CDC hdcMem;
?? hdcMem.CreateCompatibleDC(NULL);
?? CBitmap* hbmT = hdcMem.SelectObject(&m_bmpMask);
?? pDC->BitBlt( xStart, yStart, wWidth, wHeight, &hdcMem,
??????????????? xSource, ySource, SRCAND);
??
?? pDC->BitBlt(xStart, yStart, wWidth, wHeight, pTmpDC,
?????????????? xSource, ySource,SRCPAINT);
??
?? hdcMem.SelectObject(hbmT);
?? hdcMem.DeleteDC();
}
It is that simple. MSDN examples are very confusing. Chris Becke's examples are a lot better but in Win32. :)
So here is a example on how to put it together in a real life situation.
In YourDlg.h, add the following
CBitmap m_bmpPlmain;
CBitmap m_bmpMask;
BOOL LoadFileBitmap(CBitmap* pBmp, LPCTSTR szFilename);
void PrepareMask( CBitmap* pBmpSource,
CBitmap* pBmpMask,
COLORREF clrpTransColor,
int iTransPixelX = 0,
int iTransPixelY = 0 );
void DrawTransparentBitmap (CMemDC* pDC,
int xStart, int yStart,
int wWidth, int wHeight,
CDC* pTmpDC,
int xSource = 0,
int ySource = 0);
CYourDlg::OnInitDialog()
{
...
...
...
??if (!LoadFileBitmap(&m_bmpPLMain, "BmpWithHoles.bmp"))
{
}
PrepareMask( &m_bmpPLMain, &m_bmpMask, NULL, 200, 50);
}
CYourDlg::OnPaint()
{
CPaintDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap* pOldBmp = (CBitmap*) dcMem.SelectObject(&m_bmpPLMain);
DrawTransparentBitmap( &dc,
POP_X,
POP_Y,
POP_WIDTH,
POP_HEIGHT,
&dcMem,
POP_BMP_X_OFF,
POP_BMP_Y_OFF);
....
....
dcMem->SelectObject(pOldBmp);
}
CYourDlg::OnDestroy()
{
m_bmpPLMain.DeleteObject();
m_bmpMask.DeleteObject();
}
That's about it ...
Any mistakes, additions or optimizations, please feel free to point them out. Just send the comments to windev and/or raja@gelife.com.my
Raja Segar
|
Click here to view Raja Segar's online profile.
|
Other popular articles:
-
DFB vs. DIB
The difference between DFB and DIB.
-
Really cool visual FX
A set of classes for doing stunning visual effects, including water, plasma and fire.
-
CPJAImage - Yet another image drawing class
A class that draws an image with various options - transparently, disabled or grayscale, centered on or stretched to fit a given rectangle.
-
CxImage
CxImage is a C++ class to load, save, display, transform BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K images.
|
from:
http://www.codeproject.com/bitmap/transbitmapmask.asp