CBitmap aus CDC erstellen?



  • Hallo,

    ich versuche, aus einem CDC ein CBitmap zu erstellen und es will einfach nicht funktionieren. Die Internetsuche hat mich leider auch nicht weitergebracht. Mein Problem ist, daß das mit CreateCurrentBitmap() von mir erstellte CBitmap-Objekt zwar die Bildidmension, Byte pro Pixel etc. hat, die Bilddaten fehlen jedoch.

    Zum Testen hab ich das ganze einmal im OnDraw ausgeführt:

    CDC dcMem;
    dcMem.CreateCompatibleDC(pdc);
    CBitmap bmp;
    bmp.CreateCompatibleBitmap( pdc, rcBounds.right, rcBounds.bottom );
    CBitmap* pOldBitmap = dcMem.SelectObject( &bmp );
    
    // ... Diverse Zeichenvorgänge in dcMem
    
    CBitmap m_cbmpCurrentImage = dcMem.GetCurrentBitmap();
    BITMAP bitmap;
    m_cbmpCurrentImage->GetBitmap(&bitmap);
    
    pdc->BitBlt( 0, 0, rcBounds.right, rcBounds.bottom, &dcMem ,0 ,0 ,SRCCOPY );
    

    Wenn ich mir "bitmap" im Speicher anschau, dann stimmen die Bilddimensionen etc., aber der Pointer auf die Bildinformationen ist 0x000000. Mach ich beim Übertragen von dcMem irgendwas verkehrt?

    Mipe



  • Ist das hier ein Schreibfehler?

    CBitmap m_cbmpCurrentImage = dcMem.GetCurrentBitmap(); // <- Müsste fehler bringen, da GetCurrentBitmap einen Zeiger zurück gibt.
    BITMAP bitmap;
    m_cbmpCurrentImage->GetBitmap(&bitmap);
    

    Vielleicht ist sowas hier interessant für dich
    http://www.codeproject.com/bitmap/bitmapdc.asp



  • CDC dcMem;
    dcMem.CreateCompatibleDC(pdc);
    CBitmap bmp;
    bmp.CreateCompatibleBitmap( pdc, rcBounds.right, rcBounds.bottom );
    CBitmap* pOldBitmap = dcMem.SelectObject( &bmp );
    
    // ... Diverse Zeichenvorgänge in dcMem
    

    Danach sollten sich alle sich alle Zeichenoperationen im bmp befinden. Das zweite Bitmap brauchst nicht, da du einen Zeiger auf bmp erhälts. Der Aufruf von GetBitmap macht auch keine Sinn, da du die Dimensionen deines Bitmaps kennst. (Normalerweise ruft man bitmap.bmWidth und bitmap.bmHeight in BitBlit auf.)



  • Also es tut mir wirklich Leid, aber ich kapier's immer noch nicht.

    Ich habe Bildinformationen, die ich pixelweise mit SetPixelV() auf dcMem male. Anschließend möchte ich das Bild, das ich eben gemalt habe, auch als CBitmap-Objekt haben.
    Mein globaler CBitmap*-Pointer m_cbmpCurrentImage steht anfangs noch auf NULL, soll nach der Malaktion aber ein gültiges Objekt beinhalten, daß genau die Bildinformationen besitzt.

    Ich hab ja sämtliche Pixelinformationen (RGB-Werte) und hab vorher versucht, aus diesen Informationen ein Bitmap zu erzeugen (mit CreateBitmap() und Konsorten) - aber leider hab ich auch das nicht wirklich geschafft. Nur deswegen dachte ich, es wäre vielleicht einfacher, die aktuellen Daten des DC einfach in einem Bild abzuspeichern.

    Mipe



  • Kannst auch erstmal versuchen, in einen DC zu malen. Dort siehst du zumindest, ob die Zeichenoperationen funzen. Danach kopierst du den DC in einen MemoryDC, in das ein Bitmap gewählt ist.

    Mir hat der folgende Beitrag gut weitergeholfen, ist aber reine WinApi:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39400.html



  • don_basto schrieb:

    Danach kopierst du den DC in einen MemoryDC, in das ein Bitmap gewählt ist.

    Und genau das kapier ich nicht. Ich hab ein MemoryDC angelegt und den Inhalt von meinem auf folgende Art reinkopiert:

    dcNocheinMem.BitBlt( 0, 0, rcBounds.right, rcBounds.bottom, &dcMem ,0 ,0 ,SRCCOPY );
    

    Aber wie "wähl" ich jetzt hierzu ein Bitmap? Ich hab vor dem Kopieren in das MemoryDC mal folgendes probiert:

    CBitmap t;
    t.CreateCompatibleBitmap(&dcNocheinMem,m_pimgprCurrentImage->getImageWidth(),m_pimgprCurrentImage->getImageHeight());
    dcNocheinMem.SelectObject(&t);
    

    Heißt das jetzt, daß bei dem "SelectObject" der Inhalt eines vorhandenen CBitmaps in den DC gemalt wird (davon gehe ich aus) oder kann ich ihm hierdurch sagen, daß er das was er malt automatisch auch auf das zugewiesene CBitmap kopiert (davon gehe ich nicht aus und meine Tests haben auch gegenteiliges Ergeben).

    Es tut mir wirklich Leid, daß ich mich so anstelle, aber ich stochere hier in sehr trübem Gewässer und fühl mich das erste mal absolut hilflos 🙂

    Mipe



  • Wenn du ein Bitmap erstellen willst, würde ich dir folgendes vorschlagen:

    1. Zeichne in deine View, um zu prüfen, dass überhaupt was gezeichnet wird.
    2. Leg dir einen MemoryDC zu der View an (CreateCompatibleDC).
    3. Leg dir zum MemDC ein Bitmap an (CreateCompatibleBitmap).
    4. Wähle das Bitmap in den MemDC (SelectObject).
    5. Kopiere die Daten aus der View in den MemDC (BitBlit).

    Jetzt sollten die Daten im Bitmap sein. Ich drück dir die Daumen!



  • Ich dachte eigentlich, daß ich es genauso mache. Also prinzipiell klappt die Ausgabe von dem was ich zeichne recht gut. Aber zu deinen Punkten mach ich folgendes:

    /* 1. Klappt; ich male auf dcMem und übertrage am Schluß alles auf pdc */
    
    /* 2. */ 
    CDC dcMem;
    dcMem.CreateCompatibleDC(pdc);
    
    CDC dcNocheinMem;
    dcNocheinMem.CreateCompatibleDC(&dcMem);
    
    /* 3. */
    CBitmap t;
    t.CreateCompatibleBitmap(&dcNocheinMem,m_pimgprCurrentImage->getImageWidth(),m_pimgprCurrentImage->getImageHeight());
    
    /* 4. */
    dcNocheinMem.SelectObject(&t);
    
    /* Jetzt mal ich ein wenig in dcMem rum */
    
    /* 5. */
    dcNocheinMem.BitBlt( 0, 0, rcBounds.right, rcBounds.bottom, &dcMem ,0 ,0 ,SRCCOPY );	
    
    /* Um zu testen, ob jetzt ein gültiges Bitmap drin ist, hab ich noch folgendes getan. 
    Und auch wenn bei dem BITMAP-Typ die Dimensionen stimmen, ist anstatt der Bilddaten (LPVOID*) lediglich ein 0x000000 */
    BITMAP bt;
    t.GetBitmap(&bt);
    

    Vielleicht bin ich ja wirklich zu blöd dazu, aber so wie ich das mache, mach ich doch genau das, was man machen sollte, oder?

    Mipe



  • /* 1. Klappt; ich male auf dcMem und übertrage am Schluß alles auf pdc */
    // ..
    
    /* 5. */
    dcNocheinMem.BitBlt( 0, 0, rcBounds.right, rcBounds.bottom, &dcMem ,0 ,0 ,SRCCOPY );	
    pDC.BitBlt( 0, 0, rcBounds.right, rcBounds.bottom, &dcMem ,0 ,0 ,SRCCOPY );
    

    Wenn der erste Aufruf nichts dargestellt, aber der zweite Aufruf dir (wie bei erstens beschrieben) das Bitmap auf den Bildschrm zeichnet, dann weiß ich erst mal nicht weiter.



  • Ja, genau so ist es 🤡

    Ich danke dir trotzdem vielmals für deine Mühe!


Anmelden zum Antworten