Zeichnen in CBitmap



  • Hallo,

    ich möchte mir für Mathe ein kleines Prog. schreiben mit dem ich Funktionen zeichnen kann. (Mit SetPixel zum Beispiel.)
    Mein Problem ist nur, dass das Gezeichnete nicht sehr beständig ist: Wird das Fenster neu gezeichnet ist die Kurve weg!
    Andauernd Neuzeichnen geht nicht - dauert zu lange! Daher wollte ich versuchen die Kurve nur 1x zu Zeichnen und dann zu speichern: Z.B. in Cbitmap und dies dann in einem Picture-Steuerelement sichtbar machen. Nur: Wie zeichne ich in ein Cbitmap und nicht direkt auf die Form?



  • Hi
    Ist ganz einfach:
    Um in ein Bitmap zu zeichnen, musst du das Bitmap mit einem DC verbinden (=>CDC::SelectObject).
    Dann "malst" du in dein Bitmap, indem du die Aktionen auf dein DC aufrufst. z.B. CDC::SetPixel.

    Grüße Rapha



  • :xmas1: Danke! Klappt sowiet, bis auf zwei Kleinigkeiten: :xmas1:
    (m_ctlImg ist ein Picture-Steuerelement auf meiner Form.)

    CBitmap Bitmap; 
    	CDC		DC;
    	CDC*	pDC = GetDC();
    
        DC.CreateCompatibleDC(pDC); 
    	Bitmap.LoadBitmap(IDB_BITMAP1);	// Ersetzen durch CreateBitmap. Aber wie?
    	DC.SelectObject(Bitmap);
    
    	BeginWaitCursor();
    
    		DC.MoveTo(80, 500);
    
    		int y = 0;
    		for(int x = -20; x <= 20; x++)
    		{
    			y = (x * x);
    			DC.LineTo(x + 100, y + 100);
    		}
    
    	EndWaitCursor();
    
    	HBITMAP hMyBitmap = (HBITMAP) Bitmap;
    
    	pDC->BitBlt( 0, 0, 3000, 3000, &DC, 0, 0 , SRCCOPY);
    
    	m_ctlImg.SetBitmap(hMyBitmap);	// Funktioniert nicht!
    


  • Hi

    könnte vielleicht daran liegen, dass dein Bitmap-Objekt nur temporär gültig ist (Es wird ja gelöscht, wenn du die Funktion verlässt).
    Speichere das Bitmapobjekt einmal in der Dialogklasse.

    Bitmap.LoadBitmap(IDB_BITMAP1);    // Ersetzen durch CreateBitmap. Aber wie?
    

    Versuch mal:
    CBitmap::CreateCompatibleBitmap(pSourceDc, nWidth, nHeight);

    Grüße Rapha



  • Danke, das Picture-Steuerelement zeigt nun das Bild an! Es lag aber nicht an der Art der Deklaration von CBitmap, sondern an einer Einstellung am Steuerelement selbst: „Typ: Bitmap“. 💡
    Das CreateCompatibleBitmap habe ich ausprobiert. Es erstellte ein Bild mit den angegebenen Maßen. Das Bild war jedoch nicht einheitlich weiß (oder in irgendeiner anderen Farbe), sonder zeigte so ein eigenartiges Gekräusel! 😮



  • Vielleicht wird das Bitmap mit irgendwelchen Speicherresten, die in einen Farbcode umgerechnet werden, gefüllt 😃 😃



  • Muss ich das Bild dann zunächst "reinigen"? Wenn ja, wie?



  • Zeichne doch einfach ein weißes Rechteck, das so groß wie das Bild ist...



  • Ok, hat auch funktioniert. Ich habe dann versucht die Farbe zu ändern. Der Hintergrund wurde aber immer entweder nur weiß oder nur schwarz. Anscheinend habe ich nur zwei Farben zur Verfügung! Was muss ich ändern/hinzufügen um mehr Farben (256, 16 od. 32bit) zu bekommen?

    Hier mein bisheriger Code:

    CDC		DC;
    	CDC*	pDC = GetDC();
        CBitmap Bitmap; 
    
        DC.CreateCompatibleDC(pDC); 
    	Bitmap.CreateCompatibleBitmap(&DC, 500, 500);
    
    	DC.SelectObject(Bitmap);
    
    	BeginWaitCursor();
    
    		DC.FillSolidRect(0,0,500,500, 0x00ff00ff);
    		DC.MoveTo(80, 500);
    
    		int y = 0;
    		for(int x = -20; x <= 20; x++)
    		{
    			y = (x * x);
    			DC.LineTo(x + 100, y + 100);
    		}
    
    	EndWaitCursor();
    
    	HBITMAP hMyBitmap = (HBITMAP) Bitmap;
    
    	pDC->BitBlt( 0, 0, 500, 500, &DC, 0, 0 , SRCCOPY);
    
    	m_ctlImg.SetBitmap(hMyBitmap);
    


  • Hi

    den Farbwert in Hex dezimaldarstellung kannst du ganz bequem mit RGB(rot, grün, blau) berechnen (0=keine Farbe, 255=volle Farbe z.b. RGB(255, 0, 0) für rot).

    LineTo zeichnet mit dem aktuellen virtuellen Stift.
    Um die Farbe des Stiftes zu ändern, schau dir mal die Klassen CPen und CBrush an.

    Hoffe das hilft.

    Grüße Rapha



  • Lösung gefunden! : http://www.c-plusplus.net/forum/viewtopic.php?t=17331&highlight=createcompatibledc 😃 😃

    Bleibt noch eine letzte Frage: Kann ich mein Bitmap jetzt auch speichern -> Graph.bmp ?!



  • Hi,

    versuchs mal mit:

    BOOL WriteBitmap( LPTSTR szFile, HBITMAP hbitmap, HDC memdc)
    {
      BITMAP  bmp;
      if(GetObject(hbitmap, sizeof(BITMAP), &bmp))
      {
        BITMAPINFOHEADER BmpInfoHdr;  //Struktur für Bitmap-Infoheader
        BITMAPFILEHEADER BmpFileHdr;  //Struktur für Bitmap-Dateiheader
        BmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
        BmpInfoHdr.biWidth = bmp.bmWidth;
        BmpInfoHdr.biHeight = bmp.bmHeight;
        BmpInfoHdr.biPlanes = bmp.bmPlanes;
        BmpInfoHdr.biBitCount = 24;
        BmpInfoHdr.biCompression    = BI_RGB;
        BmpInfoHdr.biSizeImage        = bmp.bmWidth*bmp.bmHeight*3;
        BmpFileHdr.bfType        = 0x4d42;
        BmpFileHdr.bfReserved1        = 0;
        BmpFileHdr.bfReserved2        = 0;
        BmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
        BmpFileHdr.bfSize = BmpFileHdr.bfOffBits+BmpInfoHdr.biSizeImage;
    
        bmp.bmBits = (void*)GlobalAlloc(GMEM_FIXED, BmpInfoHdr.biSizeImage);
    
        if(GetDIBits(memdc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits,
            (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight)
        {
        HANDLE hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
         if(hFile != INVALID_HANDLE_VALUE)  {
          DWORD dwTmp;
            WriteFile(hFile, &BmpFileHdr, sizeof(BITMAPFILEHEADER), &dwTmp, NULL);
           WriteFile(hFile, &BmpInfoHdr, sizeof(BITMAPINFOHEADER), &dwTmp, NULL);
            WriteFile(hFile, bmp.bmBits,  BmpInfoHdr.biSizeImage,   &dwTmp, NULL);
            }
           CloseHandle(hFile);
        }
        GlobalFree(bmp.bmBits);
        return TRUE;
      }
     return FALSE;
    }
    

    Grüße Rapha



  • Super! Danke. Hab die Funktion eingebaut. Das Bild wird erstellt. Die Sache hat nur einen kleinen Schönheitsfehler: ➡ Das Bild ist nur weiß!

    void CBitDlg::OnButton1() 
    {
    	CDC		DC;
    	CDC*	pDC = GetDC();
        CBitmap Bitmap; 
    
        DC.CreateCompatibleDC(pDC); 
    	Bitmap.CreateCompatibleBitmap(pDC, 500, 500);
    
    	DC.SelectObject(Bitmap);
    
    	BeginWaitCursor();
    
    		DC.FillSolidRect(0,0,500,500, RGB(0,255,255));
    		DC.MoveTo(80, 500);
    
    		int y = 0;
    		for(int x = -20; x <= 20; x++)
    		{
    			y = (x * x);
    			DC.SetPixel(x + 100, y + 100, RGB(255, 0, 0));
    		}
    
    	EndWaitCursor();
    
    	HBITMAP hMyBitmap = (HBITMAP) Bitmap;
    
    	pDC->BitBlt( 0, 0, 500, 500, &DC, 0, 0 , SRCCOPY);
    
    	m_ctlImg.SetBitmap(hMyBitmap);
    
    	WriteBitmap("C:\\Windows\\Desktop\\test.bmp",  hMyBitmap, *pDC);
    }
    

Anmelden zum Antworten