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!


Anmelden zum Antworten