Bitmap aus Graphic



  • hi,

    ich würde gerne etwas gezeichnetes in ein bitmap wandeln und beim nächsten invalidate wieder zeichnen lassen, etwa so:

    void Playground::OnPaint(PaintEventArgs^ e) {
    if (m_imgBackground==nullptr)
    {
    /* wird nur einmal ausgeführt, erzeugt einen hintergrund */
    m_imgBackground = gcnew Bitmap(100, 100, e->Graphics);
    // some background drawings
    }
    e->Graphics->DrawImage(m_imgBackground, 0, 0);
    }
    

    m_imgBackground wird doch aus graphics erstellt und sollte dessen inhalt darstellen als bitmap. ich möchte den performance unterschied messen, falls sich einer fragt wieso das ganze!

    laut msdn klingt es aber anders:

    Bitmap (Int32, Int32, Graphics) : Initialisiert eine neue Instanz der Bitmap-Klasse mit der angegebenen Größe und der Auflösung des angegebenen Graphics-Objekts.

    geht es nicht so wie ich mir das denke?
    danke



  • Laut MSDN ist es nicht so wie du denkst. Ausgetestet hab ich das nicht, aber es gibt eine DrawToBitmap funktion für die meisten Controls. Mich wundert eh was du machen willst.

    Oder soll es für das Double buffering sein? Dann darfst du selber eh nur auf das Bitmap zeichnen und musst das ganze auf das Graphics Object Blitten. Dann wäre dein Ansatz richtig. Nur deine eigenen Paint operationen werden auf das Bitmap angewand und nicht auf das graphics Object von e.



  • es geht mri speziell um diese routine:

    m_imgBackground = gcnew Bitmap(100, 100, e->Graphics);
    

    das bitmap sollte wenn ich es zeichne, das wiedergeben, was ich zuvor mit e->graphics gezeichnet habe. leider klappt es nicht.sprich:

    void Playground::OnPaint(PaintEventArgs^ e) {
    if (m_imgBackground==nullptr)
    {
    /* wird nur einmal ausgeführt, erzeugt einen hintergrund */
    m_imgBackground = gcnew Bitmap(100, 100, e->Graphics);
    b = gcnew SolidBrush(Color::Red);
    r = RectangleF((x*60)+2,(y*60)+2,57,57);
    e->Graphics->FillRectangle(b,r);
    }
    e->Graphics->DrawImage(m_imgBackground, 0, 0);
    }
    

    sollte die letzte zeile nicht beim invalidate m_imgBackground zeichnen und somit
    auch das rechteck?!



  • Nein genau das ist eben nicht der Fall.

    Du machst folgendes:
    1. wenn Bitmap leer:
    1.1 Erzeuge bitmap
    1.2 Zeichne auf ein Graphics object (nicht das object von bitmap)
    2. Zeichne das (leere) Bitmap auf das Graphics Object

    Richtig wäre es, ein anderes Graphics Object vom Bitmap zu erzeugen, und dorthinein zu Zeichnen.

    Bitmap offScreenBmp; 
    Graphics offScreenDC; 
    offScreenBmp = new Bitmap(this.Width, this.Height); 
    offScreenDC = Graphics.FromImage(offScreenBmp);
    

    im Beispiel ist offSreenDc dein e
    Siehe dazu: http://www.codeguru.com/csharp/csharp/cs_graphics/drawing/article.php/c6137
    vor allem der untere bereich.

    void Playground::OnPaint(PaintEventArgs^ e) {
    if (m_imgBackground==nullptr)
    {
       m_imgBackground = gcnew Bitmap(100, 100, e->Graphics);
    }
    //Hier wäre es besser das als zusätzlichen Klassenmember zu machen
    Graphics^ bmpGfx = Graphics::FromImage(m_imgBackGround)
    b = gcnew SolidBrush(Color::Red);
    r = RectangleF((x*60)+2,(y*60)+2,57,57);
    bmpGfx->FillRectangle(b,r);
    e->Graphics->DrawImage(m_imgBackground, 0, 0);
    }
    

    Code nicht getestet



  • jap genauso war es geplant. habe es missverstanden und gedacht, dass

    m_imgBackground = gcnew Bitmap(100, 100, e->Graphics);
    

    den aktuellenen bildschirm, mit allem gezeichneten in ein bitmap transformiert 🙂
    aber es dient einfach nur dazu, zur laufzeit ein bitmap zu erzeugen, mit der auflösung und der farbtiefe des graphic objektes!

    danke nochmal!!!


Anmelden zum Antworten