CDC: Doppelpufferung und Stretch/BitBlt verwenden



  • Hi,

    ich möchte zu Testzwecken ein eine Bitmap in einen Puffer stretchen und dann aus dem Puffer mit BitBlt einen Ausschnitt in ein Fenster kopieren.

    Das laden der Bitmap ist klar, nur wie geht der Rest?
    Aber bitte: Ich MUSS die Bitmap erst in einen Puffer stretchen und dann kann ich erst einen Ausschnitt in das Fenster malen.

    Dank schonmal für eure Mühe.



  • zunächst einmal erzeugst du dir mittels createcompatibledc zwei memory dcs.
    selektiere die bitmap mittels SelectObject) in den ersten dc. in den zweiten
    musst du auch eine selektieren, da du mit diesem ansonsten nicht arbeiten kannst.
    dann machst du deinen stretchblt vom ersten in den zweiten memory dc und kopierst den ausschnit von dort aus mittels bitblt auf den screen.
    ich gehe davon aus, dass du bereits ein bitmaphandle hast ?!



  • Danke für deine schnelle Antwort.
    So in etwa habe ich das auch gemacht.

    void DrawBitmap(CPaintDC *hdc, CBitmap *Bitmap, int xStart, 
       int yStart, int br, int ho, BOOL stretch, int cx, int cy)
    {
      BITMAP bm;  //eine Bitmap-Info Struktur
    
      // Speicherkontexte
      CDC *dcmem=new CDC;
      CDC *dc=new CDC;
    
      //Informationen über die übergebene Bitmap auslesen
      Bitmap->GetObject( sizeof(BITMAP), (LPVOID)&bm); //in BM sichern
    
      dcmem->CreateCompatibleDC(hdc);
      dcmem->SelectObject( Bitmap);  //Bitmap selektieren
      dcmem->SetMapMode( hdc->GetMapMode()); //selbes Mapping wie in der Basis einstellen
    
      // BitMap mit stretch in neuen Context
      dc->CreateCompatibleDC(dcmem);
      dc->SelectObject( dcmem );  //selektieren
      dc->SetStretchBltMode(HALFTONE);
      dc->StretchBlt(0,0,br,ho,dcmem,0,0,bm.bmWidth, bm.bmHeight,SRCCOPY);
    
      hdc->SelectObject(dc);
    
      // Begrenzt auf Control Groesse (cx,cy)
      hdc->BitBlt(0,0,br,ho,dc,0,0,cx, cy,SRCCOPY);
    
      dc->DeleteDC();
      dcmem->DeleteDC();
      delete dc;
      delete dcmem;
    }
    

    Leider liefert StretchBlt immer 0 als Ergebnis, irgendwas ist da falsch.
    Kann Du mir da weiterhelfen?



  • ups Parameterfehler beim letzten BitBlt (copy & paste error), ist aber nicht der Grund der Sache ansich....



  • Ein BitBlt oder StretchBlt geht immer nur in einen "echten" DC oder in eine kompatible Bitmap. Es muss also eine solche verwendet werden um den Stretch zu machen. Von der BMP kann man dann einen beliebeigen Auschnitt ins HDC kopieren.

    Hier mal mein Code

    /*
    Einen Bitmapausschnitt in ein CPaintDC beliebig gestretcht/gestaucht zeichnen.
    hdc=Ausgabegerät
    Bitmap=eine geladene Bitmap
    xStart/yStart=x/y-Koordinate der Ausgabe im Ziel
    br,ho=Breite/Höhe in die die Bitmap gestrecht/gestaucht wird
    int cx, cy=Größe des Ausgabegerätes
    */
    void DrawBitmap(CPaintDC *hdc, CBitmap *Bitmap, int xStart, 
    				int yStart, int br, int ho, BOOL stretch, int cx, int cy)
    {
    
      BITMAP bm;  //eine Bitmap-Info Struktur 
    
      // Speicherkontexte 
      CDC *dcmem=new CDC;         //Speicherkontext für 
      CDC *dc=new CDC(); 
      CBitmap *bmp=new CBitmap;
    
      //Informationen über die übergebene Bitmap auslesen 
      Bitmap->GetObject( sizeof(BITMAP), (LPVOID)&bm); //in BM sichern 
    
      dcmem->CreateCompatibleDC(hdc); 
      dcmem->SelectObject( Bitmap);  //Bitmap selektieren 
      dcmem->SetMapMode( hdc->GetMapMode()); //selbes Mapping wie in der Basis einstellen 
    
      // BitMap mit stretch in neuen Context 
      bmp->CreateCompatibleBitmap(dcmem,ho,br);
    
      dc->CreateCompatibleDC(hdc); 
      dc->SelectObject( bmp );  //selektieren 
      dc->SetStretchBltMode(HALFTONE); 
      dc->StretchBlt(0,0,ho,br, dcmem,0,0,bm.bmWidth, bm.bmHeight,SRCCOPY); 
    
      hdc->SelectObject(dc); 
    
      // Begrenzt auf Control Groesse (cx,cy) 
      hdc->BitBlt(0,0,cx,cy,dc,0,0,SRCCOPY); 
    
      dc->DeleteDC(); 
      dcmem->DeleteDC(); 
      delete dc; 
      delete dcmem; 
      delete bmp;
    }
    

    Funktioniert recht gut bei mir, kann aber sicher noch verbessert werden...
    Hab dank und Gruss


Anmelden zum Antworten