|
Hi thanks for this nice article.I have succeeded to compile this application & run it.
But to no avail i am able to see a tranparent bitmap.All i can see is the given input image ,No tranparency is applied.
I want to apply tranparency to the text drawn into the Bitmap.My Bitmap is created with GDI+ method & text is drawn using GDI(DrawText for Performance).I get Color object from GDI+ to be applied to Text.GDI only takes RGB values from Color object of GDI+ , No Alpha.
Any help or direction is greatly appreciated.
|
|
|
|
|
This code is really cool! I looked for that kind of solution for hours, and eventually found your code. It is neat, clean cut, and works like a charm.
I'll bring some small suggestions also:
add the background color to be substituted to the transparency color in PrepareMask, i.e.:
-----------------------
in include ...h file:
void PrepareMask(CBitmap* pBmpSource, CBitmap* pBmpMask, COLORREF clrpTransColor, COLORREF clrpBkgColor, int iTransPixelX = 0, int iTransPixelY = 0);
and in ...cpp file, replace RGB(0,0,0):
//hdcSrc.SetBkColor(RGB(0,0,0)); // ... if bakground must be black
hdcSrc.SetBkColor(clrpBkgColor);
-----------------------
add the BMP mask as an argument of DrawTransparentBitmap, i.e.:
-----------------------
in include ...h file:
declare as many CBitmap masks as you have bitmaps to handle, then declare :
void DrawTransparentBitmap(CDC* pDC, int xStart, int yStart, int wWidth, int wHeight, CDC* pTmpDC, CBitmap *pBmpMask, int xSource = 0, int ySource = 0);
and in ...cpp file, in this function code:
...
CBitmap* hbmT = hdcMem.SelectObject(pBmpMask);
...
-----------------------
This way, you can have several small bitmaps to be handled in your application and treat them all, in OnInitDialog and OnPaint. And you can have the correct bakcground color subtituted to transparent one, especially with the trick of pixel 0,0 as transparency reference for each.
Thanks a lot for this great solution. It is particularly appreciated in a MFC Windows environment where OO is not particularly well thought by Microsoft...
|
|
|
|
|
What if I have a bitmap, with some transparent regions and that I want to render with different sizes ?
|
|
|
|
|
ie Is there any function like TransparentStretchBlt ?
|
|
|
|
|
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 ...
|
|
|
|
|
|
First of all you should check your code before posting.
|
|
|
|
|
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
|
|
|
|
|
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?
|
|
|
|
|
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();
}
}
|
|
|
|
|
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?
|
|
|
|
|
I sure that there are limitation to 256 colors in some situations.
|
|
|
|
|
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.
|
|
|
|
|
Just noticed an error here, the Create call has to have ILC_COLOR24 | ILC_MASK if you still want to use transparency. The initial example only works because TRUE and ILC_MASK happen to both be 1.
|
|
|
|
|
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!
|
|
|
|
|
So how about telling the rest of us what you did to get it to work?
|
|
|
|
|
I had the same problem, here's how I solved it
----------- In CMyDlg::DrawTransparentBitmap -----------
...
<br />
CBitmap* hbmT = hdcMem.SelectObject(&m_bmpMask);<br />
<br />
pDC->BitBlt( xStart, yStart, wWidth, wHeight, &hdcMem,<br />
xSource, ySource, SRCAND);<br />
<br />
<br />
hdcMem.SelectObject(&m_bmpPlmain);
pDC->BitBlt(xStart, yStart, wWidth, wHeight, pTmpDC,<br />
xSource, ySource, SRCPAINT);<br />
...
------------------
Best Regards
Sergio Del Valle
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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!
|
|
|
|
|
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);
}
|
|
|
|
|
The word CRollupCtrl should be replaced by the name of the class in which you are implementing this function.
|
|
|
|
|
This is a best way, thank you. The way the author presented doesn't work well, the colorts of my bitmap get changed.
Late
|
|
|
|
|
thank you for your best code~!!
|
|
|
|
|
Hours dealing with the sample code and copy paste with Tim @ Fit code, god bless you buddy.
|
|
|
|
|