CodeFatal
Erfahrenes Mitglied
Hi @ all,
hab da mal wieder nen Problem und nen dickes Brett vorm Kopf. Bin schon lange am basteln und testen aber nix klappt mehr.
Ich habe mir soweit möglich die Ergebnisse des folgenden Codes anzeigen lassen und die Bit-Operationen eigentlich auch verstanden (denke ich).
Ausgangssituation:
Will ne Bitmap aus ner Datei laden (klappt)
Will die Transparent in einem Dialogfeld basierenden Dialog darstellen (klappt)
Will die Zoomen können (klappt)
Will die in nem bestimmten Teil des Dialoges darstellen (klappt)
Transparenz an und abschaltbar (klappt)
Soweit so gut.
Fehler auftreten:
Wenn ich keine Transparenz Rechnerei mache ist alles super sobald aber Transparenz mit dazu kommt geht irgendwas schief, sobald ich den dialog invalidiere.
z.B.: wird kurzzeitig von nem anderen Fenster überdeckt oder ausserhalb des Bildschirms bewegt.
Wird die Transparente Fläche dann wieder sichtbar, ist sie nicht mehr Transparent sondern Schwarz.
Um das Ganze im gesamten zu realisieren, habe ich die Klasse CPaintDC abgeleitet und folgende Funktion hinzugefügt:
Zur Erklärung der Parameter:
CMyBitmap *pBMap - Zeiger auf Daten der Bitmap
CRect Zoom - Rechteck in das von Cut ausgeschnittene Bildpunkte projeziert werden
CRect Cut - Rechteck das aus der Bitmap Bereich ausschneidet (grösser als Bitmap-> Verkleinerung der Anzeige)
CDC *pDc - Zeiger auf das endgültige Ziel Device
DWORD Flag - für spätere Verwendung
COLORREF AlphaColor - Alphafarbe wenn keine farbe gewünscht -1
Ich verwende MFC unter .Net.
Hoffe es gibt hier nen hilfbereiten Menschen, der sich die Mühe macht der Kram einmal durchzu sehen und auch noch feststellt, wo ich den gedanklichen Fehler habe.
Gruss und Danke schon mal für eunre Hilfe
Michael
hab da mal wieder nen Problem und nen dickes Brett vorm Kopf. Bin schon lange am basteln und testen aber nix klappt mehr.
Ich habe mir soweit möglich die Ergebnisse des folgenden Codes anzeigen lassen und die Bit-Operationen eigentlich auch verstanden (denke ich).
Ausgangssituation:
Will ne Bitmap aus ner Datei laden (klappt)
Will die Transparent in einem Dialogfeld basierenden Dialog darstellen (klappt)
Will die Zoomen können (klappt)
Will die in nem bestimmten Teil des Dialoges darstellen (klappt)
Transparenz an und abschaltbar (klappt)
Soweit so gut.
Fehler auftreten:
Wenn ich keine Transparenz Rechnerei mache ist alles super sobald aber Transparenz mit dazu kommt geht irgendwas schief, sobald ich den dialog invalidiere.
z.B.: wird kurzzeitig von nem anderen Fenster überdeckt oder ausserhalb des Bildschirms bewegt.
Wird die Transparente Fläche dann wieder sichtbar, ist sie nicht mehr Transparent sondern Schwarz.

Um das Ganze im gesamten zu realisieren, habe ich die Klasse CPaintDC abgeleitet und folgende Funktion hinzugefügt:
Code:
BOOL CMyPaintDC::DrawBitmap(CMyBitmap *pBMap,CRect Zoom, CRect Cut, CDC *pDc, DWORD Flag,COLORREF AlphaColor)//zeichnet Bitmap in DC falls Alpha im Bereich von COLORREF wird Alpha kanal mit berechnet
{
CBitmap* bmp=NULL;
CBitmap* oldbmp=NULL;
CBitmap* oldbmpmask;
BITMAP *BitmapParam; // Parameter der Bitmaps
CBitmap CMaskBmp;
CBitmap *pCBmp;
CDC dc2,dc2mask;
// --- Speicher-DC für zu zeigendes Bild
dc2.CreateCompatibleDC(pDc);//Zeichenfläche von CBitmap
// --- Speicher-DC fuer Bitmap-Maske erstellen ---
dc2mask.CreateCompatibleDC(pDc);//Bitmap für alphamaske
if(bmp)
{
pCBmp = pBMap->GetCBitmap();
// Bitmap-Groesse auslesen
BitmapParam = pBMap->GetBitmapInfo();
int m_nTransBmpWidth = BitmapParam->bmWidth;
int m_nTransBmpHeight = BitmapParam->bmHeight;
// und geladene Transparent Bitmap auswaehlen
oldbmp = dc2.SelectObject(bmp);//Bild Original in Speicher laden
if(AlphaColor>=0 && AlphaColor<=0x00ffffff)//wenn eine gültige AlphaFarbe gesetzt
{
// zuerst monochromes (s/w) CBitmap-Objekt in der gleichen
// Groesse wie eingelesen Bitmap erstellen
CMaskBmp.CreateBitmap( m_nTransBmpWidth, m_nTransBmpHeight, 1, 1, NULL );
// und Masken-Bitmap auswaehlen
oldbmpmask = dc2mask.SelectObject(&CMaskBmp);//jetzt ist in dc2mask eine einheitliche Fläche in der Grösse des Bitmaps Schwarz uninitialisiert
// --- S/W Bitmap erstellen ----
dc2.SetBkColor(AlphaColor);
// geladene Bitmap in monochrome Bitmap umkopieren
// -> alles ausser Alphafarbe erscheint nun in schwarzer Farbe
dc2mask.BitBlt(0,0,m_nTransBmpWidth,m_nTransBmpHeight,&dc2,0,0, SRCCOPY );//alles was in dc2 nicht Hintergrund von dc2 entspricht, wird nach dc2mask kopiert, HG von dc2mask ist weiß
// Aus Orignal-Bitmap Hintergrund entfernen
dc2.SetBkColor(RGB(255,255,255));//wenn nicht wird Alphafarbe bei oder mit eingerechnet 255 invertieren->0 oder was anderes = was anderes
// Negativ von S/W Bitmap, HG ist nun schwarz (RGB:0,0,0)
dc2mask.BitBlt(0,0,m_nTransBmpWidth,m_nTransBmpHeight,NULL,0,0, DSTINVERT );//maske einfach invertieren daher NULL
// geladene Bitmap mit negativ von S/W-Bitmap verunden
// --> HG der geladenen Bitmap ist nun schwarz
dc2.BitBlt(0,0,m_nTransBmpWidth,m_nTransBmpHeight,&dc2mask,0,0, SRCAND );//Alphafarbe ist durch schwarz ersetzt worden bei maske ist alles außer Alphafarbe weiss
// Mask wieder restaurieren (HG ist weiss = 0xFFFFFF)
dc2mask.BitBlt(0,0,m_nTransBmpWidth,m_nTransBmpHeight,NULL,0,0, DSTINVERT );//wie oben alles ausser Alphafarbe ist Schwarz
// Bitmap-Umrisse ausschneiden aus Hintergrund
// Umrisse der Bitmap aus dem HG ausschneiden
pDc->SetTextColor(RGB(0,0,0));
pDc->SetBkColor(RGB(255,255,255));
pDc->StretchBlt(Zoom.left,Zoom.top,Zoom.Width(),Zoom.Height(),&dc2mask,Cut.left,Cut.top,Cut.Width(),Cut.Height(),SRCAND);//alles was bisher auf dc gezeichnet wurde und die maske -> alles tiefer liegende + "Schatten" von dem was noch kommt
// Bitmap einkopieren
// Zum Versuchen: auch einmal diesen Aufruf entfernen
pDc->StretchBlt(Zoom.left,Zoom.top,Zoom.Width(),Zoom.Height(),&dc2,Cut.left,Cut.top,Cut.Width(),Cut.Height(),SRCPAINT);//alles was bisher auf dc gezeichnet wurde und die maske -> alles tiefer liegende + "Schatten" von dem was noch kommt
dc2mask.SelectObject(oldbmpmask);
}
else//kein Alpha
{
pDc->StretchBlt(Zoom.left,Zoom.top,Zoom.Width(),Zoom.Height(),&dc2,Cut.left,Cut.top,Cut.Width(),Cut.Height(),SRCCOPY);//alles was bisher auf dc gezeichnet wurde und die maske -> alles tiefer liegende + "Schatten" von dem was noch kommt
}
dc2.SelectObject(oldbmp);
}
dc2mask.DeleteDC();
dc2.DeleteDC();
return TRUE;
}
CMyBitmap *pBMap - Zeiger auf Daten der Bitmap
CRect Zoom - Rechteck in das von Cut ausgeschnittene Bildpunkte projeziert werden
CRect Cut - Rechteck das aus der Bitmap Bereich ausschneidet (grösser als Bitmap-> Verkleinerung der Anzeige)
CDC *pDc - Zeiger auf das endgültige Ziel Device
DWORD Flag - für spätere Verwendung
COLORREF AlphaColor - Alphafarbe wenn keine farbe gewünscht -1
Ich verwende MFC unter .Net.
Hoffe es gibt hier nen hilfbereiten Menschen, der sich die Mühe macht der Kram einmal durchzu sehen und auch noch feststellt, wo ich den gedanklichen Fehler habe.
Gruss und Danke schon mal für eunre Hilfe
Michael