Bilder kombinieren



  • Hallo, ich bin neu hier und hoffe auf proffesionelle Hilfe.

    Meine Programmierkenntnisse sind leider beschränkt, vor allem was die MFC angeht, sorry also schon mal im Voraus für die warscheinlich vielen dummen Fragen...

    Ich versuche mit der MFC mehrere Bitmaps zu manipulieren. Am Ende soll rauskommen, dass ich die einzelnen Pixel der Bitmaps geziehlt verändern kann (mit SetPixel schon klar).

    Ich habe also eine Klasse implementiert, in der 3 HBITMAP Variablen drin sind. Ein Objekt dieser Klasse wird im Doc initialisiert.

    Ich lade zwei Bitmaps mit HIlfer von Memberfunktionen von der Festplatte in die ersten zwei Variablen der Klasse. Diese kann ich auch anzeigen, das funktioniert tadellos.

    Mein Problem ist nun die Erstellung des dritten Bitmaps. Dieses Bitmap soll (zumindest für den Anfang) aus den ersten beiden Bitmaps zusammengesetzt werden. Der Einfachheit halber sind die Bitmaps gleich breit, so dass ich quasi ein neues Bitmap haben möchte, das den Inhalt der ersten beiden enhällt, und einfach doppelt so hoch ist. Ausgelöst wird die Zusammensetzung mit einer Funktion. Diese Funktion soll die ersten beiden Bitmaps nehmen, zusammensetzen und in der dritten Variable abspeichern. Das so erstellte Bild braucht nicht auf der Festplatte gespeichert werden, es reicht, wenn ich es anzeigen lassen kann.

    Da ich in der MFC bisher nur recht anspruchslose Sachen gemacht habe, komme ich irgendwie mit den ganzen Gerätekontexten nicht klar (CDC / HDC). Das ist im Mom einfach zu hoch für mich...

    Den Code den ich bisher habe, poste ich hier:

    [cpp]
    void CScrollerView::OnBildzusammen()
    {
    	CScrollerDoc* pDoc = GetDocument();
    		ASSERT_VALID(pDoc);
    
    /*********************************************************************************/
    //Erstes bild in Array einlesen
    	HBITMAP Bild1;
    	BITMAP ParameterBild1;
    
    	Bild1 = pDoc->pBitmap.m_hBitmap1; //Bild1 holen
    	CDC *BildSpeicher1 = new CDC;//neuen Speicher DC erstellen
    	BOOL bRetCode = BildSpeicher1->CreateCompatibleDC(0); //
    		ASSERT(bRetCode);
    
    	CBitmap* pCBitmap1 = CBitmap::FromHandle(Bild1);
    	BildSpeicher1->SelectObject(pCBitmap1);
    
    	pCBitmap1->GetBitmap(&ParameterBild1);
    
    //Mit den so gespeicherten Werten sollen später Operationen ausgeführt werden
    /*	vector< vector<int> > BildDaten1 = make_2DimVector<int>( ParameterBild1.bmHeight, ParameterBild1.bmWidth );
    
    	for (int i = 0; i < ParameterBild1.bmHeight; i++)
    	{
    		for (int j = 0; j < ParameterBild1.bmWidth; j++)
    		{
    			BildDaten1[i][j] = BildSpeicher1->GetPixel(j,i);
    		}
    	}*/	
    /*********************************************************************************/
    
    /*********************************************************************************/
    //Zweites Bild in Array einlesen
    	HBITMAP Bild2;
    	BITMAP ParameterBild2;
    
    	Bild2 = pDoc->pBitmap.m_hBitmap2; //Bild2 holen
    	CDC *BildSpeicher2 = new CDC;//neuen Speicher DC erstellen
    	bRetCode = BildSpeicher2->CreateCompatibleDC(0); //
    		ASSERT(bRetCode);
    
    	CBitmap* pCBitmap2 = CBitmap::FromHandle(Bild2);
    	BildSpeicher2->SelectObject(pCBitmap2);
    
    	pCBitmap2->GetBitmap(&ParameterBild2);
    
    //Mit den so gespeicherten Werten sollen später Operationen ausgeführt werden
    	/*vector< vector<int> > BildDaten2 = make_2DimVector<int>( ParameterBild2.bmHeight, ParameterBild2.bmWidth );
    
    	for (int i = 0; i < ParameterBild2.bmHeight; i++)
    	{
    		for (int j = 0; j < ParameterBild2.bmWidth; j++)
    		{
    			BildDaten2[i][j] = BildSpeicher2->GetPixel(j,i);
    		}
    	}*/	
    /************************************************************************************/
    
    /*********************************************************************************/
    //Bilder Zusammenfügen, dafür einen Speicher DC erstellen, der beide Bilder enthällt
    	CDC *BildSpeicherGesammt = new CDC;
    	BildSpeicherGesammt->CreateCompatibleDC(0);
    
    	//Handel auf die Membervariable des Documents
    	CBitmap* pCBitmapGesammt = CBitmap::FromHandle(pDoc->pBitmap.m_hBitmapGesammt);
    	BildSpeicherGesammt->SelectObject(pCBitmapGesammt);
    
    	//PixelDaten in den Gesammtspeicher schreiben
    	for (int i = 0; i < (ParameterBild1.bmHeight + ParameterBild2.bmHeight); i++)
    	{
    		if (i <= ParameterBild1.bmHeight)
    		{
    			for (int j = 0; j < ParameterBild1.bmWidth; j++)
    			{
    				BildSpeicherGesammt->SetPixel(j,i,BildSpeicher1->GetPixel(i,j));
    			}
    		}
    		else
    		{
    			for (int j = 0; j < ParameterBild2.bmWidth; j++)
    			{
    				BildSpeicherGesammt->SetPixel(j,i,BildSpeicher2->GetPixel(i-ParameterBild1.bmHeight,j));
    			}
    		}
    	}
    
    	HDC       /*hScrDC,*/ hMemDC = NULL; //Speicher DC für das Neue Bild
    	HBITMAP    /*hBitmap,*/ hOldBitmap;
    	int       nX, nY, nX2, nY2;
    	int       nWidth, nHeight;
    
    	hMemDC = CreateCompatibleDC(0);
    
    	SelectObject(hMemDC,pCBitmapGesammt); //Gesammtbild im Speicher abbilden
    
        nX = 0;
        nY = 0;
        nX2 = ParameterBild1.bmWidth; //breite der Bilder
        nY2 = ParameterBild1.bmHeight + ParameterBild2.bmHeight; //höhe der Bilder zusammen
        nWidth = nX2 - nX;
        nHeight = nY2 - nY;
    
    	pDoc->pBitmap.m_hBitmapGesammt = CreateCompatibleBitmap(hMemDC, nWidth, nHeight); //Membervariable mit Speicher DC initialisieren
        hOldBitmap = (HBITMAP)SelectObject(hMemDC, pDoc->pBitmap.m_hBitmapGesammt);
    	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hMemDC, nX, nY, SRCCOPY);
        pDoc->pBitmap.m_hBitmapGesammt = (HBITMAP)SelectObject(hMemDC, pCBitmapGesammt);
    
        DeleteDC(hMemDC);
    
    /*********************************************************************************/
    }
    [/cpp]
    

    Ich hoffe der Code löst nicht allzuviel Gelächter aus, ich bin halt doch noch sehr unerfahren.

    Das Stück Code, dass die eigentliche Abspeicherung übernimmt habe ich übrigens hier aus dem Forum, im Original funktioniert das auch (es wird ein Bildschirmfoto gemacht und abgespeichert).

    Das Problem ist, das ich da irgendwo ein Fehler mache (oder auch mehrere), es wird nur ein schwarzes Bild angezeigt. Irgendwie bekomme ich es nicht hin, die Daten der ersten Bilder in das dritte zu kopieren. Kann mir jemand von euch helfen? Ich bin für jede Hilfe dankbar.

    mfg Stephan



  • Hallo

    also ich habs jetzt mit Trick 17 hinbekommen:

    Ich hab den Code der hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-105563-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-hdc+cdc-and-start-is-10.html
    verwendet wird um einen Screenshot darzustellen genommen. Diesen geringfügig geändert und das so gespeicherte Bild einfach erneut geladen und verändert...

    Und siehe da, die von mir gemachten Änderungen bleiben in der Membervariable bestehen und die Anzeige klappt super. Mehr wollte ich ja nicht.


Anmelden zum Antworten