Bitmap laden, aber transparente farbe ??
-
hi,
wie ich bilder aus geladenen dateien anzeigen kann weiß ich schon, aber ich brauche ne funktion die eine bestimmte farbe transparent darstellen kann.
diese funktion benutze ich bisher:
OleLoadPicturePath(L"I:\\Projekte\\TEST\\CBitmap\\Mpg, Gif alden\\Debug\\pcf002.gif", 0, 0, 0, IID_IPicture,(void **) &m_bild);
// ein bischen warten damit variable kopiert werden kann ...
long x = 10;
long y = 10;
long size_x = 468;
long size_y = 60;CClientDC dc(this);
CRect rc;
GetClientRect(&rc);OLE_XSIZE_HIMETRIC width;
OLE_YSIZE_HIMETRIC height;bild->get_Width(&width);
bild->get_Height(&height);bild->Render(dc, x, y, size_x, size_y, 0, height, width, -height, &rc);
kann mir da jemand weiterhelfen ??
-
Hallo Red Skall,
Die Klasse CDC bietet die Funktionen SetPixel und GetPixel. Mit ihnen kannst du die Farbe einzelner Pixel abfragen und setzten. Du musst das Bild nur in ein von CDC abgeleitetes Objekt laden ( Wie bei CClientDC ) und dann alle Pixel in einer Schleife abfragen, nach der gewählten Farbe und wenn sie diese Farbe besitzten eine neue Farbe zuweisen mit SetPixel.
Die Funktionen sind in der MSDN beschrieben.
Turbobrain
-
sorry, aber wie soll das gehen ?? kannst du mir das nen bischen genauer erklären !?
kome da so wirklich nicht weiter
-
Also als ersten Tip, such in der MSDN die beiden Funktion (Stichwort GetPixel reicht). Schau sie dir an.
Dann zu deinem Programm:
Lade dein Bild wie gehabt mit OleLoadPicturePath, setzte die Größen.
Dann erzeugst du den DC. Hierbei weis ich nicht genau ob CClientDC die Funktionen unterstützt, probier es aus wenn es net geht, erzeuge den DC mitCDC dc;Dann holst du dir das ClientRect wie gehabt. Erstelle dann eine Variable vom Typ COLORREF, die die transparente Farbe aufnimmt (Achtung bei der Zuweisung, kein RGB möglich).
Bevor du das Bild anzeigst, muss eine Doppelschleife kommen:for(int x = 0; x++; x < x_size des Bildes in Pixeln) { for(int y = 0; y++; y < y_size des Bildes in Pixeln) { hier kommt Pixel Abfrage { }In diese Schleife schreibst du eine If-Abfrage, wenn der mit GetPixel geholte COLORREF-Wert gleich der transparentfarbe ist, setzte ihn mit SetPixel Transparent.
Als x bzw. y für die Funktionen SEt und GetPixel nimmst du die Zählvariablen der Schleifen.
Turbobrain
-
Öhm, also entweder ich steh voll daneben oder keiner hat bisher in den MFC-FAQ danach gesucht.
-
Zu CrazyOwl:
Entweder bin ich wirklich blind, oder das Thema existiert nicht in der FAQ. Daher werde ich die Frage von Red Skall beantworten.Zu turbobrain:
Dein Vorschlag ist zwar sehr gut, entspricht aber nicht dem Präfix deines Benutzernamens - besonders nicht wenn große Bilder transparent gestaltet werden sollen.Beantwortung der Urprungs-Frage:
Wenn du Bilder transparent anzeigen lassen willst, empfehlen sich dazu oft nur Bitmaps (*.bmp), da GIFs oder JPGs häufig einen mehrfarbigen Hintergrund enthalten, der aufgrund der Kompression entsteht. Daher lässt sich der Hintergrund nur schwer transparent zeichnen. Bitmaps läd man schnell wie gefolgt:CString szFileName = "C:\\MyBitmapFile.bmp"; HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);Wenn du das Bitmap-Handle hast, rufst du die unten stehende Funktion auf. Erklärung der Parameter:
pDC: Gerätekontext, auf den du das Bild zeichnen willst
hBmp: Handle deines Bitmaps
x,y: Obere linke Ecke des "neuen" Bildes
crColour: Transparente Farbe, z.B. RGB(0, 0, 255) für blauDie Funktion:
void DrawTransparent(CDC * pDC, HBITMAP hBmp, int x, int y, COLORREF crColour) { COLORREF crOldBack = pDC->SetBkColor(m_crWhite); COLORREF crOldText = pDC->SetTextColor(m_crBlack); CBitmap pMyBitmap; CDC dcImage, dcTrans; // Attach bitmap pBitmap.Attach(hBmp); // Create two memory dcs for the image and the mask dcImage.CreateCompatibleDC(pDC); dcTrans.CreateCompatibleDC(pDC); // Select the image into the appropriate dc CBitmap* pOldBitmapImage = dcImage.SelectObject(this); // Create the mask bitmap CBitmap bitmapTrans; int nWidth = Width(); int nHeight = Height(); bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL); // Select the mask bitmap into the appropriate dc CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans); // Build mask based on transparent colour dcImage.SetBkColor(crColour); dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY); // Do the work - True Mask method - cool if not actual display pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND); pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); // Restore settings dcImage.SelectObject(pOldBitmapImage); dcTrans.SelectObject(pOldBitmapTrans); pMyBitmap.Detach(); pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText); }____________________________________________________
PS: Sollte das Thema transparente Bilder tatsächlich nicht in der FAQ stehen, empfehle ich dieses Thema dort hineinzustellen.
-
Zwei kleine Fehler im 2. Code!
FALSCH: pBitmap.Attach(hBmp);
RICHTIG: pMyBitmap.Attach(hBmp);FALSCH: CBitmap* pOldBitmapImage = dcImage.SelectObject(this);
RICHTIG: CBitmap* pOldBitmapImage = dcImage.SelectObject(&pMyBitmap);____________________________________________________
Ich bitte um Verständnis!
-
Hab ich das Problem etwa völlig falsch verstanden, naja jedenfalls das ist das was ich gemeint hab:
http://www.c-plusplus.net/forum/viewtopic.php?t=39066
-
1000 dank, das hilft bestimmt. ich probiers gleich mal aus
:p

habs gerade ausprobiert, es läuft ^^
-
Hallo!
Wollte gerade mal die Funktion nachvollziehen, aber es hagelt insgesamt fünf Fehlermeldungen:
error C2065: 'm_crWhite' : nichtdeklarierter Bezeichner
error C2065: 'm_crBlack' : nichtdeklarierter Bezeichner
error C2065: 'Width' : nichtdeklarierter Bezeichner
error C2065: 'Height' : nichtdeklarierter Bezeichner
error C2664: 'DrawTransparent' : Konvertierung des Parameters 1 von 'class CPaintDC' in 'class CDC *' nicht moeglich
Kein benutzerdefinierter Konvertierungsoperator verfuegbar, der diese Konvertierung durchfuehren kann, oder der Operator kann nicht aufgerufen werden
Fehler beim Ausführen von cl.exe.Ich hab das ganze im OnPaint-Ereignis aufegerufen:
CPaintDC dc(this); // device context for painting // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen // Transparentes Bitmap erzeugen HBITMAP hbitmap = ::LoadBitmap(m_hInstance,MAKEINTRESOURCE(IDB_BOSCH)); DrawTransparent(dc,hbitmap,20,20,RGB(0,0,255));
-
habs so gemacht:
void CProgramm::DrawTransparent(CDC * pDC, HBITMAP hBmp)
{
int x = 110; // standart parameter
int y = 110; // standart parameter
COLORREF crColour; // standart parameter
CRect rc;GetClientRect(rc);
crColour = crTransparent;
COLORREF crOldBack = pDC->SetBkColor(RGB(255, 255, 255));
COLORREF crOldText = pDC->SetTextColor(RGB(0, 0, 0));
CBitmap pMyBitmap;
CDC dcImage, dcTrans;// Attach bitmap
pMyBitmap.Attach(hBmp);// Create two memory dcs for the image and the mask
dcImage.CreateCompatibleDC(pDC);
dcTrans.CreateCompatibleDC(pDC);// Select the image into the appropriate dc
CBitmap* pOldBitmapImage = dcImage.SelectObject(&pMyBitmap);// Create the mask bitmap
CBitmap bitmapTrans;
int nWidth = rc.Width();
int nHeight = rc.Height();
bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL);// Select the mask bitmap into the appropriate dc
CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans);// Build mask based on transparent colour
dcImage.SetBkColor(crColour);
dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY);// Do the work - True Mask method - cool if not actual display
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);
pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND);
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);// Restore settings
dcImage.SelectObject(pOldBitmapImage);
dcTrans.SelectObject(pOldBitmapTrans);
pMyBitmap.Detach();
pDC->SetBkColor(crOldBack);
pDC->SetTextColor(crOldText);
}und so hab ich das programm aufgerufen:
CDC *MPdc = GetDC();
((CWhiteEvalDlg*)GetParent())->DrawTransparent(MPdc, hBmp);
die werte für transparenz uns x, y mußte ändern, ist ja klar
und das mit 'CRect rc' hab ich erstmal so gemacht zum testen. aber die größe vom bitmap hab ich noch nicht raus
-
Red Skall schrieb:
habs so gemacht:
void CProgramm::DrawTransparent(CDC * pDC, HBITMAP hBmp)
{
int x = 110; // stan**** parameter
int y = 110; // stan**** parameter
COLORREF crColour; // stan**** parameter
CRect rc;GetClientRect(rc);
crColour = RGB(10, 10, 10); // das ist jetzt die transparente farbe
COLORREF crOldBack = pDC->SetBkColor(RGB(255, 255, 255));
COLORREF crOldText = pDC->SetTextColor(RGB(0, 0, 0));
CBitmap pMyBitmap;
CDC dcImage, dcTrans;// Attach bitmap
pMyBitmap.Attach(hBmp);// Create two memory dcs for the image and the mask
dcImage.CreateCompatibleDC(pDC);
dcTrans.CreateCompatibleDC(pDC);// Select the image into the appropriate dc
CBitmap* pOldBitmapImage = dcImage.SelectObject(&pMyBitmap);// Create the mask bitmap
CBitmap bitmapTrans;
int nWidth = rc.Width();
int nHeight = rc.Height();
bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL);// Select the mask bitmap into the appropriate dc
CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans);// Build mask based on transparent colour
dcImage.SetBkColor(crColour);
dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY);// Do the work - True Mask method - cool if not actual display
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);
pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND);
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);// Restore settings
dcImage.SelectObject(pOldBitmapImage);
dcTrans.SelectObject(pOldBitmapTrans);
pMyBitmap.Detach();
pDC->SetBkColor(crOldBack);
pDC->SetTextColor(crOldText);
}und so hab ich das programm aufgerufen:
CDC *MPdc = GetDC();
((CWhiteEvalDlg*)GetParent())->DrawTransparent(MPdc, hBmp);
die werte für transparenz uns x, y mußte ändern, ist ja klar
und das mit 'CRect rc' hab ich erstmal so gemacht zum testen. aber die größe vom bitmap hab ich noch nicht raus
-
Hallo, ich bin's noch mal.
Erstmal: Entschuldigung für die 5 Fehler, Phips!. Den Quelltext hatte ich aus einer eigenen Klasse kopiert, ohne an die Ausdrücke zu denken, die dort zwar definiert sind, 'global' aber ungültig sind. Zwar sind die Fehler von den Kollegen fast behoben worden, aber trotzdem möchte ich sie dir noch mal der Reihe nach verbessern:
- Ersetze m_crWhite durch RGB(255, 255, 255)
- Ersetze m_crBlack durch RGB(0, 0, 0)
- Ersetze Width() durch die Breite des Bildes
- Ersetze Height() durch die Höhe des Bildes
- Ändere deinen Code um in:
CPaintDC dc(this); // device context for painting // Transparentes Bitmap erzeugen HBITMAP hbitmap = ::LoadBitmap(m_hInstance,MAKEINTRESOURCE(IDB_BOSCH)); DrawTransparent(&dc, hbitmap, 20, 20, RGB(0,0,255));zu 3) und 4): Du kannst auch einfach zwei neue Parameter zur Funktion geben, die Breite und Höhe des Bildes erwarten.
________________________________________________________________
Ich bitte erneut um Verständnis und hoffe, dass nun alles läuft!
-
Danke!
Jetzt klappts auch bei mir!
-
jetzt hab ich wieder was neues:
ich habe jetzt alle bilder auf mein dialogfeld gezeichnet. wenn ich jetzt aber irgend ein neues bild zeichnen will, kommt einfach ein scharzes feld !?
ich hab erstmal ein buschen rumprobiert, aber auch wenn ich ein bild nehme, was noch nicht geöffnet ist, kommt ein schwarzes feld !?ich hab keine ahnung was das ist

-
Hallo,
ich habe die Unteraltung verfolgt und dann ausprobiert, ob es auch bei mir klappt. Ich habe ein Dialogfeldbasierende Anwendung erstellt. Sie lässt sich ohne Fehler kompilieren. Aber wenn ich das Bild anzeigen will (beim Klicken auf einen Button) zeigt er nichts. Woran kann das liegen?
Turbobrain
-
@ turbobrain: zeigt er ne fehlermeldung an oder macht er einfach nichts ?? vielleicht haste kein ereignis auf dein button hinzugefügt
. Scherz, aber beschreib bitte etwas genauer. könnte mir nähmlich vorstellen das du einfach einen total dummen fehler gemacht hast oder was übersehen hast, so ist es bei mir ziemlich oft !!(hat auch einer ne antwort auf meine frage nur so nebenbei ??)
-
ich habe keine ahnung was ich an meinen code gemacht habem aber auf einmal geht es ^^ *freu*

jetzt kommt das bitmap was ich haben will !!jetzt brauchen wir nur noch ne antwort für turbobrain

-
Hallo Red Skall,
du wolltest eine Beschreibung meines Problems.
Also ich habe den Code der hier im Beitrag geschrieben wurde übernommen und die Variablen angepasst. Dann habe ich das Bitmap mit LoadBitmap geladen, und dann DrawTransparence aufgerufen wie du, nur mit allen Parametern.
Wenn ich das Programm ausführe wird kein Fehler angezeigt, doch wenn ich dann auf den Button drücke um das Bild anzuzeigen, passiert nichts.
Bitte um Hilfe.
Turbobrain
-
probiers mal mit
HBITMAP hBmp; // erst noch das bitmap laden ... DrawTransparent(GetDC(), hBmp);oder falls du das getan hast ruf das mal in OnPaint() auf und nimm den schon in OnPaint() erzeugten DC (CDC dc).
vielleicht klappts. könnte mir nichts anderes vorstellen
ich machs ja auch so. und wenn er nichts macht, dann kann es eigentlich nur heißen das er nicht auf dem DC malst auf dem du malen willst *vermut*