Come creare un grande CC di memoria compatibili nella programmazione GDI?

StackOverflow https://stackoverflow.com/questions/881270

  •  22-08-2019
  •  | 
  •  

Domanda

Voglio creare un grande CompatibleDC, disegnare un'immagine di grandi dimensioni su di esso, allora parte BitBlt dell'immagine da altri DC, al fine di ottenere prestazioni elevate.

Sto usando il seguente codice per creare memoria compatibile con DC. Ma quando il rettangolo diventa molto grande, ecc: 5000 * 5000, il CompatibleDC CREATO diventare instabile. a volte è OK, a volte non è riuscito. c'è qualche cosa di sbagliato con il mio codice?

input :pInputDC
output:pOutputMemDC

{
    pOutputMemDC=new CDC();
    VERIFY(pOutputMemDC->CreateCompatibleDC(pInputDC));

    CRect rect(0,0,nDCWidth,nDCHeight);
    CBitmap bitmap; 
    if (bitmap.CreateCompatibleBitmap(pInputDC, rect.Width(), rect.Height()))
    {
        pOutputMemDC->SetViewportOrg(-rect.left, -rect.top);
        m_pOldBitmap = pOutputMemDC->SelectObject(&bitmap);
    }
    CBrush brush;
    VERIFY(brush.CreateSolidBrush(RGB(255,0, 0)));
    brush.UnrealizeObject();
    pOutputMemDC->FillRect(rect, &brush);
}
È stato utile?

Soluzione

Invece di creare un grande DC e quindi blitting una porzione di un altro, più piccolo DC, creare una CC della stessa dimensione come destinazione DC, o almeno la stessa dimensione come destinazione blit. Poi, offset tutti i comandi di disegno da parte del (-x, -y) della sezione sub che si desidera copiare. Se la vostra destinazione è (100.200) -. (400.400) sulla fonte quindi creare un CC (300x200) e l'offset per tutto (-100, -200)

Questo ha due grandi vantaggi: in primo luogo, la memoria necessaria è molto più piccolo. In secondo luogo, GDI agganciare le operazioni di disegno per le dimensioni della DC (passa sempre clip in ogni caso). Sebbene l'atto di clipping richiede tempo CPU, il tempo risparmiato non disegnando pixel che non si vedono più che compensa.

Ora, se questo grande DC è qualcosa di simile a un'immagine (JPEG per esempio), allora avete bisogno di guardare in altri metodi. Una tecnica utilizzata da molti programmi di editing delle immagini è quella di dividere l'immagine in piastrelle e pagina le piastrelle da / per / disco rigido di memoria. Ogni piastrella è proprio DC e hai solo DC sorgente abbastanza per riempire il bersaglio DC. Come la finestra di visualizzazione si sposta attraverso l'immagine grande, scaricare le piastrelle che hanno spostato fuori delle piastrelle rettangolo di destinazione e di carico che sono diventati visibili.

Altri suggerimenti

Ogni immagine 5000x5000 pixel ha bisogno di ca. 100MB di RAM. A seconda della quantità di RAM del PC ha, questo potrebbe già essere il problema.

Se si dispone di 1 GB di RAM o più, allora che probabilmente non è il problema. In questo caso, è necessario disporre di una perdita di memoria. Dove si libera la bitmap assegnato? Vedo che unrealize il pennello ma come circa il bitmap?

Si noti che aumentando lo swap non aiuterà dal momento che uccidono le prestazioni.

Assicurarsi che si sta selezionando tutti GDI originali oggetti per i PVS.

Il problema potrebbe essere che il vostro Bitmap è ancora selezionato nella pOutputMemDC quando viene distrutto e uno di essi o entrambi non può essere eliminato in modo corretto. Così problemi di memoria potrebbero cominciare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top