|
Eine transparente Darstellung einer Bitmap über einer anderen arbeitet mit einer Farbe, die als transparente Farbe definiert wird, so daß jedes Pixel, das diesen Farbwert besitzt, nicht neu gezeichnet wird. Für eine semitransparente Darstellung hat hingegen eine Überlagerung der Pixel zu erfolgen, so daß die beiden Farbwerte miteinander verknüpft werden müssen.
Die allgemeine Vorgehensweise für das überlagerte Anzeigen zweier Bitmaps besteht darin, für die beiden beteiligten Bitmaps A und B jeweils jeden Farbwert der Pixel durch eine Konstante zu dividieren und die resultierenden Ergebnisse zu addieren, um einen neuen Farbwert zu erhalten, der Anteile beider Farbwerte enthält. Eine mögliche Formel ist
Result = A*a + B*(1-a)
wobei „a“ ein Gewichtungsfaktor ist, mit dem sich die Intensität der Farbabdämpfung steuern läßt.
Diese Methode arbeitet mit Gleitkommazahlen und ist demzufolge sehr rechenaufwendig, wenngleich die Resultate sehr gut sind. Soll die Berechnung in erster Linie schnell erfolgen, kann die nachfolgende Methode verwendet werden. Diese macht sich einige Vereinfachungen zunutze, die im Rechner schneller abgearbeitet werden können als Gleitkommaoperationen. DrawSemiTransparentBitmap() entspricht bis auf den letzten Parameter der Aufrufstruktur der Funktion BitBlt().
Realisiert ist die Funktion über BitBlt()-Aufrufe über compatible Kontexte, wobei zunächst ein Auffüllen des Zielkontextes mit einer „Maskenfarbe“ erfolgt.
void DrawSemiTransparentBitmap(CDC *pDstDC,
int x, int y,
int nWidth, int nHeight,
CDC* pSrcDC,
int xSrc, int ySrc)
{
CDC dcCompatible;
CBitmap *pBitmapOld;
CBitmap bm;
dcCompatible.CreateCompatibleDC(pDstDC);
bm.CreateCompatibleBitmap(pDstDC, nWidth, nHeight);
pBitmapOld = dcCompatible.SelectObject(&bm);
dcCompatible.FillSolidRect(CRect(0, 0, nWidth, nHeight),
RGB(0x7F, 0x7F, 0x7F));
pDstDC->BitBlt(x, y, nWidth, nHeight,
&dcCompatible, 0, 0, SRCAND);
dcCompatible.SelectObject(pBitmapOld);
pDstDC->BitBlt(x, y, nWidth, nHeight,
pSrcDC, 0, 0, SRCPAINT);
}
Das erste BitBlt() entfernt das höchstwertige Bit jedes Pixels im Zielkontext, während der zweite Aufruf den Quellkontext auf den Zielkontext kopiert. Dies führt zu einer Sättigung der hellen Farben, was aber in den meisten Anwendungsfällen kein Problem bereitet.
Result = (A and 0x7F) + B
Spielt diese Sättigungsproblematik keine Rolle, genügt das letzte BitBlt(). Als Ergebnis ergibt sich dann ein Image mit stärkerer Sättigung, wenn viele helle Farben verwendet werden, da die Formel
Result = A + B
für A und B zu Werten größer als 255 führt, was infolge der anschließenden Modulo-Operation Sättigung bewirkt.
| Lösung
|