Zwei Bitmaps übereinander zeichnen und zweites Bitmap invertieren?



  • Hi!

    Ich habe zwei Bitmaps:
    m_bmpOrig enthält ein Bild, das von der Festplatte geladen wurde
    m_bmpWork enthält Linien, die der Benutzer zeichnet

    Ich möchte nun m_bmpOrig anzeigen und dann m_bmpWork darüberlegen, dabei soll m_bmpWork aber so dargestellt werden, dass man die Linien immer sieht, sie müssen also irgendwie invertiert werden.

    Wie kann ich das anstellen?

    BOOL CFotovermessungDlg::ImgShow()
    {
    	CDC* pDC = this->m_statFRM.GetDC();
    	CDC dcMem;
    	dcMem.CreateCompatibleDC(pDC);
    
    	CRect lrect;
    	this->m_statFRM.GetClientRect(&lrect);
    
        CBitmap bitmap;
    	bitmap.CreateCompatibleBitmap(pDC, lrect.right, lrect.bottom);
    
        CBitmap* oldBitmap = dcMem.SelectObject(&bitmap);
    
    	Gdiplus::Graphics graphics(dcMem.m_hDC);
    
    	graphics.Clear(Gdiplus::Color::White);
    
    	if(this->m_bmpOrig != NULL)
    		graphics.DrawImage(this->m_bmpOrig,
    		this->m_ptOrigin.x, this->m_ptOrigin.y,
    		this->GetImgWidth(this->m_bmpOrig), this->GetImgHeight(this->m_bmpOrig));
    
    	pDC->BitBlt(0,0, lrect.right, lrect.bottom, &dcMem, 0,0, SRCCOPY);
    	graphics.Clear(Gdiplus::Color::White);
    
    	if(this->m_bmpWork != NULL)
    		graphics.DrawImage(this->m_bmpWork,
    		this->m_ptOrigin.x, this->m_ptOrigin.y,
    		this->GetImgWidth(this->m_bmpWork), this->GetImgHeight(this->m_bmpWork));
    
    	pDC->BitBlt(0,0, lrect.right, lrect.bottom, &dcMem, 0,0, SRCINVERT);
    
    	dcMem.SelectObject(oldBitmap);
    
    	return 0;
    }
    

    So klappt es leider nicht, da muss was grundsätzliches falsch sein, denn so habe ich auch ein invertiertes m_bmpOrig auf dem Schirm, das aber im Originalzustand erhalten bleiben soll. Muss man für soetwas 2 Mal blitten oder geht das irgendwie anders?

    Gruß



  • Ich habe noch weiter rumgepfuscht und bin zumindest zu einem Ergebnis gekommen, das so funktioniert, wie ich will. 🙂

    BOOL CFotovermessungDlg::ImgShow()
    {
    	CDC* pDC = this->m_statFRM.GetDC();
    	CDC dcMem, dcMem2;
    	dcMem.CreateCompatibleDC(pDC);
    	dcMem2.CreateCompatibleDC(pDC);
    
    	CRect lrect;
    	this->m_statFRM.GetClientRect(&lrect);
    
        CBitmap bitmap, bitmap2;
    	bitmap.CreateCompatibleBitmap(pDC, lrect.right, lrect.bottom);
    	bitmap2.CreateCompatibleBitmap(pDC, lrect.right, lrect.bottom);
    
        CBitmap* oldBitmap = dcMem.SelectObject(&bitmap);
        CBitmap* oldBitmap2 = dcMem2.SelectObject(&bitmap2);
    
    	Gdiplus::Graphics graphics(dcMem.m_hDC);
    
    	graphics.Clear(Gdiplus::Color::White);
    
    	if(this->m_bmpOrig != NULL)
    		graphics.DrawImage(this->m_bmpOrig,
    		this->m_ptOrigin.x, this->m_ptOrigin.y,
    		this->GetImgWidth(this->m_bmpOrig), this->GetImgHeight(this->m_bmpOrig));
    
    	dcMem2.BitBlt(0,0, lrect.right, lrect.bottom, &dcMem, 0,0, NOTSRCCOPY);
    	graphics.Clear(Gdiplus::Color::White);
    
    	if(this->m_bmpWork != NULL)
    		graphics.DrawImage(this->m_bmpWork,
    		this->m_ptOrigin.x, this->m_ptOrigin.y,
    		this->GetImgWidth(this->m_bmpWork), this->GetImgHeight(this->m_bmpWork));
    
    	dcMem2.BitBlt(0,0, lrect.right, lrect.bottom, &dcMem, 0,0, SRCINVERT);
    
    	pDC->BitBlt(0,0, lrect.right, lrect.bottom, &dcMem2, 0,0, SRCCOPY);
    
    	dcMem.SelectObject(oldBitmap);
    	dcMem2.SelectObject(oldBitmap2);
    
    	return 0;
    }
    

    Das ist aber vermutlich zu umständlich und fehleranfällig. Deshalb bin ich wie immer für Verbesserungsvorschläge offen 🙂

    Gruß



  • GDI ist zwar leicht, aber ned meins. Ich nutze ja stattdessen das brandneue Direct2D
    welches aber leider statt AdvancedBlending nur TransparencyBlending nutzt.
    Achte einfach auf die Drawing-Order (in BackToFront-manner) und auch auf korrekte Blending-Stage States sowie AlphaInhalt deiner Bitmaps.


Anmelden zum Antworten