BMP transparent machen funktioniert nicht bei mir
-
Hallo liebes Forum,
In meinem Programm werden einige Icons für Statusinformationen angezeigt.
Es sind BItmaps mit einer Frabtiefe von 4 Bit.
Durch den bisher fixen Hintergrund der Anwendung erschienen einige Bereiche
der Icons transparent.
Nun möchte ich den Hintergrund flexibel habe. Deshalb sollen die Icons
tatsächlich transparent werden.Ich habe schon die ganzen Tutorials und Beispiele und Foren (auch dieses)
durchsucht. Ich finde immer ähnliche Codes aber brng das bei mir nicht
zum Laufen.Meine Ausgangs-Methode: (zeigt einfach nur das Icon an)
void CViewX::OutBitmap(CDC* pDC,CDC *pCompatibleDC, WORD wBitmapNr,RECT* pRect) { CBitmap sBitmap; BITMAP bm; sBitmap.LoadBitmap(wBitmapNr); sBitmap.GetObject(sizeof(BITMAP), &bm); CBitmap * oldBitmap = pCompatibleDC->SelectObject(&sBitmap); pDC->StretchBlt(pRect->left,pRect->top,pRect->right-pRect->left,pRect->bottom-pRect->top, pCompatibleDC, 0, 0,bm.bmWidth, bm.bmHeight,SRCCOPY ); pCompatibleDC->SelectObject(oldBitmap); sBitmap.DeleteObject(); }
Transparenz: Diese Farbe soll transparent werden: (200,200,230)
Versuch 1: (hier ist alles transparent. Ich sehe kein Icon mehr)void CViewX::OutBitmap(CDC* pDC,CDC *pCompatibleDC, WORD wBitmapNr,RECT* pRect)// pDcImage = CompatibleDC { CBitmap sBitmap; BITMAP bm; int iRectX = pRect->left; int iRectY = pRect->top; int iRectWidth = pRect->right - pRect->left; int iRectHight = pRect->bottom - pRect->top; sBitmap.LoadBitmap(wBitmapNr); sBitmap.GetObject(sizeof(BITMAP), &bm); CBitmap* pOldBitmap = pCompatibleDC->SelectObject(&sBitmap); TransparentBlt((HDC)(&pDC), iRectX, iRectY, iRectWidth, iRectHight, (HDC)(&pCompatibleDC), 0, 0, iRectWidth, iRectHight, (200,200,230)); pCompatibleDC->SelectObject(pOldBitmap); sBitmap.DeleteObject(); }
Versuch 2: (gibt mir einfach mein altes Bitmap aus)
void CViewX::OutBitmap(CDC* pDC,CDC *pCompatibleDC, WORD wBitmapNr,RECT* pRect)// pDcImage = CompatibleDC { CBitmap sBitmap; CBitmap* pBmpMask; CDC CompatibleDCMask; BITMAP bm; int iRectX = pRect->left; int iRectY = pRect->top; int iRectWidth = pRect->right - pRect->left; int iRectHight = pRect->bottom - pRect->top; COLORREF crOldBack = pDC->SetBkColor((255,255,255)); COLORREF crOldText = pDC->SetTextColor((0,0,0)); CompatibleDCMask.CreateCompatibleDC(pDC); sBitmap.LoadBitmap(wBitmapNr); sBitmap.GetObject(sizeof(BITMAP), &bm); CBitmap* pOldBitmap = pCompatibleDC->SelectObject(&sBitmap); pBmpMask = new CBitmap(); pBmpMask->CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL); CBitmap* pOldBitmapMask = CompatibleDCMask.SelectObject(pBmpMask); pCompatibleDC->SetBkColor((200,200,230));// Diese Farbe soll nachher transparent sein! CompatibleDCMask.StretchBlt(0, 0, iRectWidth, iRectHight, pCompatibleDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY ); pDC->StretchBlt(iRectX, iRectY, iRectWidth, iRectHight, pCompatibleDC, 0, 0, bm.bmWidth, bm.bmHeight ,SRCINVERT ); pDC->BitBlt(iRectX, iRectY, iRectWidth, iRectHight, &CompatibleDCMask, 0, 0, SRCAND); pDC->StretchBlt(iRectX, iRectY, iRectWidth, iRectHight, pCompatibleDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT); pCompatibleDC->SelectObject(pOldBitmap); CompatibleDCMask.SelectObject(pOldBitmapMask); pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText); sBitmap.DeleteObject(); pBmpMask->DeleteObject(); }
Was mache ich denn falsch?
Ich habe schon alle möglichen Flags und Permutationen im Code probiert.Vielen Dank schon mal.
Grüsse
-
Kannst du überhaupt C++?
Die Parameterübergabe mittels ((255,255,255)) ist falsch!
Schau dir die Doku an: CDC::SetBkColor und übergebe den richtigen Datentyp COLOREF ("To create a COLORREF color value, use the RGB macro.")...
Selbiges gilt dann für die anderen COLORREF-Parameter.
-
Vielen Dank Th69 für die Antwort.
An dem Fehler lag es. Die lange Version funktioniert nun.
Ich würde nie behaupten, dass ich in C++ alles kann, obwohl ich schon eine
Weile damit arbeite. Dazu gibt es viel zu viele Teilgebiete, als dass
überhaupt jemand das von sich behaupten könnte.
Die Grafik Sachen sind allerdings schon ein neues Feld für mich.
Leider hat der Compiler nicht gemeckert.
Und sowas passiert eben. Und auch wenn man´s gewusst hätte, sitzt man
manchmal tagelang davor, ohne es zu sehen.Allerdings hat sich für die "TransparentBlt"-Methode nichts geändert.
Die verhält sich leider immer noch so wie zuvor. (nur der Neugier halber...)
-
Ich hoffe mal, du verstehst, warum der Compiler nicht gemeckert hat und was er bei (255,255,255) interpretiert (Stichwort: Komma-Operator)?
Zu deinem konkreten Problem bzgl. der Transparenz kann ich dir wenig helfen - debugge einfach mal und schau, ob diese Farbe wirklich in der Bitmap vorkommt (mir kommt suspekt vor, daß du von 4bit Farbtiefe sprichst [also mit einer Farbpalette???], aber die Farben im RGB-Format angibst).
-
Na ja, wie schon gesagt, in der Grafik Programmierung bin ich noch recht
unbeholfen. Das mit dem falschen Datentyp und der Compiler Reaktion ist
nachträglich auch zu verstehen.Die Spezifikation der Bitmaps zeigt mir Das Eigenschaften-Fenster von Windows an.
Und die RGB-Farben gibt mir eben die Farbpalette von Paint so zurück.
Andere Datentypen kenne ich nicht (oder noch nicht). Finde auch in den Foren
dazu nur diese. Und die Verwendung von Bitmaps in einem "View" ist bei Windows
(laut verschiedener Quellen) nur für 4 Bit BMP spezifiziert (genau wie bei den
Windows Buttons). Und die gewünschte Untermenge für die 4 Bit kann man sich
dabei aus der Palette zusammenstellen.Das Programm habe ich nicht erstellt, sondern entwickle es nur weiter, und da
waren diese RGB-Datentypen schon so drin.Da die lange Methode der beiden nun funktioniert, kann es nicht am Bitmap liegen.
Ich muss für die Verwendung von dem "TransparentBlt(..)" noch Fehler gemacht
haben. Den Datentyp habe ich natürlich korrigert!