DWORD adwTransparentColors[] =3D
{ 0, BLACK, WHITE, GRAY, LightGRAY, RED,
LightRED, GREEN, LightGREEN, BLUE,
LightBLUE, YELLOW, GOLD, CYAN,
LightCYAN, VIOLET, LightVIOLET };
Die generelle Vorgehensweise besteht aus mehreren Schritten. Zunächst muß die transparente Farbe C festgelegt werden.
Als nächstes muß ein Speicherkontext dcTemp erzeugt und die Bitmap in diesen Kontext selektiert werden:
void TBitMap::Draw(TDC& dc, int x, int y)
{
TBitmap *bitmap;
try
{
bitmap =3D new TBitmap(pchName);
if (nTransClrIndex)
{
TPoint ptSize;
COLORREF cTransparentColor =
adwTransparentColors[nTransClrIndex];
TMemoryDC dcTemp;
dcTemp.SelectObject(*bitmap);
Die nächsten Schritte bestehen darin, einen weiteren monochromen Speicherkontext dcBack in exakt der Größe der Ausgangsbitmap zu beschaffen.
Die Hintergrundfarbe von dcTemp wird nun auf C gesetzt und dcBack auf die Ausgangsbitmap per BitBlt() mit RC-opcode MERGECOPY abgebildet. Dies erzeugt die benötigte Maske. Abschließend werden Vorder- und Hintergrund der Ausgangsbitmap auf Weiß bzw. Schwarz gesetzt:
ptSize.x =3D bitmap->Width();
ptSize.y =3D bitmap->Height();
dcTemp.DPtoLP(&ptSize, 1);
TMemoryDC dcBack;
TMemoryDC dcObject;
TMemoryDC dcMem;
TMemoryDC dcSave;
TBitmap bmAndBack(ptSize.x, ptSize.y, 1, 1, NULL);
TBitmap bmAndObject(ptSize.x, ptSize.y, 1, 1, NULL);
TBitmap bmAndMem(dc, ptSize.x, ptSize.y);
TBitmap bmSave(dc, ptSize.x, ptSize.y);
dcBack.SelectObject(bmAndBack);
dcObject.SelectObject(bmAndObject);
dcMem.SelectObject(bmAndMem);
dcSave.SelectObject(bmSave);
dcTemp.SetMapMode(dc.GetMapMode());
dcSave.BitBlt(0, 0, ptSize.x, ptSize.y,
dcTemp, 0, 0, SRCCOPY);
TColor cClr =3D dcTemp.SetBkColor(cTransparentColor);
dcObject.BitBlt(0, 0, ptSize.x, ptSize.y,
dcTemp, 0, 0, SRCCOPY);
dcTemp.SetBkColor(cClr);
Wird nun die Maske mit BitBlt() und NOTSRCCOPY auf die Ausgangsbitmap abgebildet, werden alle Pixel der Ausgangsbitmap auf die transparente Farbe oder schwarz gesetzt:
dcBack.BitBlt(0, 0, ptSize.x, ptSize.y,
dcObject, 0, 0, NOTSRCCOPY);
MemDC wird nun mit der Masken-Bitmap besetzt:
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y,
dc, x, y, SRCCOPY);
Jetzt werden für DC Hinter- und Vordergrundfarben auf weiß bzw. schwarz gesetzt. Danach erfolgt ein BitBlt () mit SRCAND von dcMem auf DC. Abschließend wird die modifizierte Original-Bitmap in dcMem selektiert und dcMem mit Operand SRCPAINT per BitBlt auf DC abgebildet:
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y,
dcObject, 0, 0, SRCAND);
dcTemp.BitBlt(0, 0, ptSize.x, ptSize.y,
dcBack, 0, 0, SRCAND);
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y,
dcTemp, 0, 0, SRCPAINT);
dc.BitBlt(x, y, ptSize.x, ptSize.y,
dcMem, 0, 0, SRCCOPY);
dcTemp.BitBlt(0, 0, ptSize.x, ptSize.y,
dcSave, 0, 0, SRCCOPY);
}
else
{
TMemoryDC memDC;
memDC.SelectObject(*bitmap);
dc.BitBlt(x, y, bitmap->Width(), bitmap->Height(),
memDC, 0, 0 );
}
delete bitmap;
}
catch ( ... )
{
}
}
Mit dieser Vorgehensweise können komplexe Bitmaps transparent ausgegeben werden.
| Farbwerte
|