|
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
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 63 (Total in Forum: 63) (Refresh) | FirstPrevNext |
|
|
 |
|
|
 |
|
|
 |
|
|
canu plz tell me how can i get the Dimensioned biamtp after using BitBlt in CBitmap or HBITMAP object , like
CPaintDC dc( this ); // Device context for painting
CBitmap bmp, *poldbmp; CDC memdc;
// Load the bitmap from Computer (orignal res is 400x 200 ) bmp.DeleteObject(); bmp.Attach(::LoadImage(AfxGetInstanceHandle(),_T("D:\\test.bmp"),IMAGE_BITMAP,0,0, LR_LOADFROMFILE));
// Create a compatible memory DC memdc.CreateCompatibleDC( &dc );
// Select the bitmap into the DC poldbmp = memdc.SelectObject( &bmp );
// Copy (BitBlt) bitmap from memory DC to screen DC dc.BitBlt( 0, 0, 57, 75, &memdc, 0, 0, SRCCOPY );
memdc.SelectObject( poldbmp )
now problem is i want that new DIMENSIONED BITMAP to copy in the CBimap or HBITMAP object . plz plz plzz help me on this .
Thanx ...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hi,
I have two tiff images and I am loading them into CBitmap using GDI Bitmap class. I am using one of the image to paint the background of a dialog and its working fine. Now I would like to use the second image to draw on top of the first. The second image has some transaparent areas and those areas should be replaced with the image in the back( first image).
I tried several examples in Codeproject, But I am getting the transaparent area filled with blue.
Can someone pl. guide me on doing this.
Thanks San
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I am writing an application using embedded visual c++ 4.0 and I am having trouble with the offscreen buffering. I have searched the web over and over and they all lead me back to the simple techniques used in this article. However, I still see a bad screen flicker in my Pocket PC app no matter what technique I try.
My app is a Pocket PC 2003 MFC dialog based, where I am trying to draw to an offscreen bitmap and then use BitBlt() to load the bitmap. The flicker is actually worse when I use this technique over not doing any buffering.
Can anyone give me some advice or a pointer as to what needs to be done different for the pocket pc enviornment? Or better yet, possibly some sample code of a pocket pc app that is flicker free?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
you can use CImageList to load bmp, and to show it transparently.
here's the example
in OnInitDialog CBitmap bm; bm.LoadBitmap(IDB_BITMAP1); m_imageList.Create(100,100,TRUE,1,1); m_imageList.Add(&bm,RGB(0,0,0));
in OnPaint if (IsIconic()){...} else { CPoint pt(0,0); CPaintDC dc(this); imageList.Draw(&dc,0,pt,ILD_NORMAL); CDialog::OnPaint(); } }
|
| Sign In·View Thread·PermaLink | 3.67/5 (3 votes) |
|
|
|
 |
|
|
Both CImageList and drawing transparent bitmap codes work fine. However, when printing to a postscript printer or creating a PDF file, the whole image is black using both codes? Any idea?
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Depends on how you create the image list:
CImageList ImgList; ImgList.Create(xsize, ysize, ILC_COLOR24, 1, 1);
This lets you create an image list that does 24-bit color bitmaps.
Jason Tost
Engineer Wavelength Electronics Inc.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, I appreciate your efforts in attempting to share this with all but couldn't you have tested it properly first?
I have just wasted the best part of an hour trying to get it to work!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I had the same problem, here's how I solved it
----------- In CMyDlg::DrawTransparentBitmap -----------
...
CBitmap* hbmT = hdcMem.SelectObject(&m_bmpMask);
pDC->BitBlt( xStart, yStart, wWidth, wHeight, &hdcMem, xSource, ySource, SRCAND);
// Also note the use of SRCPAINT rather than SRCCOPY.
// Set the bitmap to be drawn hdcMem.SelectObject(&m_bmpPlmain); //<- Added by Sergio Del Valle pDC->BitBlt(xStart, yStart, wWidth, wHeight, pTmpDC, xSource, ySource, SRCPAINT);
...
------------------
Best Regards Sergio Del Valle
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
This code was very helpful. However, I had to fix a small problem to get it to work correctly. Before BitBlt-ing the monochrome mask onto the destination DC, you must set the background color of the destination DC to white and the text color to black. Then, when the mask is converted to color before the actual blt, the colors are such that the SRCAND raster op has the desired effect.
If I'm in error, I apologize. It does seem like somebody would have seen this earlier.
dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
You are correct. Spot-on.
Without doing the above, one ends up with odd results - what appeared on my machine (Vista 32 running default theme) as a smeared look to the resulting image (I adapted the above code along with CImageButtonWithStyle, also on CodeProject) to vastly improve the look of those buttons, and fix the problems XP has with themed BS_PUSH_LIKE buttons.
I found two things necessary to fix this example code to fully work:
1. Apply David's "problem" above. 2. Copy the source bitmap to a target-device compatible DC, and always use the GetPixel to extract the clipping color (rather than rely upon RGB(n,n,n)), as the color of the pixel is defined by the pixel depth.
Now that I'm using a target-dc compatible source bitmap and I'm setting the target DC's text & bkcolor's before clipping it, I find that all works perfectly.
Cheers!
Steve Wolf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm trying to use the code you posted, but I'm getting a whole bunch of errors as soon as I include CMemDC.h file. Errors start with the line:
CMemDC(CDC* pDC ) : CDC() { pDC->GetClipBox(&m_rect); Construct(pDC); }
I tried several versions of the file, useless.
First error: error C2059: syntax error : ')'
pointing to the line above.
Please help!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Add this function to your code and then call it. The following code could be used to call this function
// IDB_BITMAP1 is the resource id HBITMAP bmA = ::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
// Source dc ClientDC dc(this);
// X coord. to draw the bitmap on the distination dc short xStart = 0;
// Y coord. to draw the bitmap on the distination dc short yStart = 0;
// The color inside the HBITMAP that should be transparent COLORREF cTransparentColor = RGB(255,0,255);
DrawTransparentBitmap(dc.m_hDC, bmA, xStart, yStart, cTransparentColor);
------------------------------------------------------------
void CRollupCtrl::DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart, short yStart, COLORREF cTransparentColor) { BITMAP bm; COLORREF cColor; HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave; HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; POINT ptSize;
hdcTemp = CreateCompatibleDC(hdc); SelectObject(hdcTemp, hBitmap); // Select the bitmap
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); ptSize.x = bm.bmWidth; // Get width of bitmap ptSize.y = bm.bmHeight; // Get height of bitmap DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
// to logical points
// Create some DCs to hold temporary data. hdcBack = CreateCompatibleDC(hdc); hdcObject = CreateCompatibleDC(hdc); hdcMem = CreateCompatibleDC(hdc); hdcSave = CreateCompatibleDC(hdc);
// Create a bitmap for each DC. DCs are required for a number of // GDI functions.
// Monochrome DC bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// Monochrome DC bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
// Each DC must select a bitmap object to store pixel data. bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack); bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject); bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem); bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
// Set proper mapping mode. SetMapMode(hdcTemp, GetMapMode(hdc));
// Save the bitmap sent here, because it will be overwritten. BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
// Set the background color of the source DC to the color. // contained in the parts of the bitmap that should be transparent cColor = SetBkColor(hdcTemp, cTransparentColor);
// Create the object mask for the bitmap by performing a BitBlt // from the source bitmap to a monochrome bitmap. BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
// Set the background color of the source DC back to the original // color. SetBkColor(hdcTemp, cColor);
// Create the inverse of the object mask. BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
// Copy the background of the main DC to the destination. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);
// Mask out the places where the bitmap will be placed. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
// Mask out the transparent colored pixels on the bitmap. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
// XOR the bitmap with the background on the destination DC. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
// Copy the destination to the screen. BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);
// Place the original bitmap back into the bitmap sent here. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
// Delete the memory bitmaps. DeleteObject(SelectObject(hdcBack, bmBackOld)); DeleteObject(SelectObject(hdcObject, bmObjectOld)); DeleteObject(SelectObject(hdcMem, bmMemOld)); DeleteObject(SelectObject(hdcSave, bmSaveOld));
// Delete the memory DCs. DeleteDC(hdcMem); DeleteDC(hdcBack); DeleteDC(hdcObject); DeleteDC(hdcSave); DeleteDC(hdcTemp); }
|
| Sign In·View Thread·PermaLink | 3.14/5 (5 votes) |
|
|
|
 |
|
|
The word CRollupCtrl should be replaced by the name of the class in which you are implementing this function.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is a best way, thank you. The way the author presented doesn't work well, the colorts of my bitmap get changed.
Late
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I was trying to attach several images to one file, and bmp, jpg worked well.. but icon didn't work as intended.
bool CxImageICO::Decode(CxFile *hFile) { ... hFile->Seek(icon_list[page].dwImageOffset, SEEK_SET); ... }
because this code reset current reading point to first of file, invalid data will be read if other data exists before icon images.
so I patched like this (yeah, I referenced ximajpg.cpp's decode func.)
bool CxImageICO::Decode(CxFile *hFile) { DWORD off = hFile->Tell(); ... hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET); .. }
simple. but works well =) and... WMF file also has same problem -_-;; after searching bug, I'll post again.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
NULL is as same value as black(0x00000000) color. Though user specify black as a clrpTransColor value,
if (clrpTransColor == NULL) { // User did not specify trans color so get it from bmp clrTrans = hdcSrc.GetPixel(iTransPixelX, iTransPixelY); } This code will regard it as default value NULL. As valid RGB value is from 0x00000000 to 0x00FFFFFF, I suggest default value 0xFF000000 or bigger than that.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hi everyone 
I try to do a random function on the pictures of my pocket pc 2002 (does with embedded visual c++), the pictures do not change even when the whole program itself reloaded!!
can you help me please to know why ????
my e-mail is: nelaji@yahoo.com
thank-you!
nelaji@yahoo.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|