Comment créer un grand DC mémoire compatible dans la programmation GDI?

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

  •  22-08-2019
  •  | 
  •  

Question

Je veux créer un grand CompatibleDC, dessiner une grande image, puis BitBlt partie de l'image à l'autre DC, afin d'obtenir des performances élevées.

Je suis en utilisant le code suivant pour créer DC mémoire compatible. Mais quand le rect devient très grand, etc: 5000 * 5000, le CompatibleDC créé instable. parfois, il est OK, parfois, il a échoué. est-il quelque chose de mal avec mon code?

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);
}
Était-ce utile?

La solution

Au lieu de créer un grand courant continu et blitting alors une partie de celui-ci une autre, plus petite DC, créer un courant continu de la même taille que le DC destination, ou au moins la même taille que la destination blit. Ensuite, offset toutes vos commandes de dessin par la (-x, -y) de la sous-section que vous souhaitez copier. Si votre destination est (100200) -. (400400) la source puis créer un courant continu (300x200) et décalé tout en (-100, -200)

Cela a deux avantages: d'une part, la mémoire requise est beaucoup plus petite. En second lieu, GDI coupera vos opérations de dessin à la taille de la DC (il toujours des clips de toute façon). Bien que l'acte de coupure prend du temps CPU, le temps économisé en ne tirant pixels qui ne sont pas visibles à plus fait pour elle.

Maintenant, si ce grand DC est quelque chose comme une image (JPEG par exemple), vous devez regarder dans d'autres méthodes. Une technique utilisée par de nombreux programmes d'édition d'image est de diviser l'image en tuiles et la page des tuiles à / de la mémoire / disque dur. Chaque tuile est son propre DC et vous avez seulement assez de contrôleurs de domaine source pour remplir la cible DC. Comme la fenêtre de vue se déplace sur la grande image, décharger les tuiles qui ont quitté les tuiles rectangle cible et charge qui sont devenus visibles.

Autres conseils

Chaque image pixel 5000x5000 a besoin ca. 100 Mo de RAM. Selon la quantité de RAM de votre PC a, cela pourrait déjà être le problème.

Si vous avez 1 Go de RAM ou plus, alors c'est probablement pas la question. Dans ce cas, vous devez avoir une fuite de mémoire. Où voulez-vous libérer le bitmap alloué? Je vois que vous unrealize la brosse, mais que diriez-vous du bitmap?

Notez que l'augmentation de votre échange ne sera pas utile car cela tuerait la performance.

Assurez-vous que vous sélectionnez tous les objets GDI d'origine aux contrôleurs de domaine.

Le problème peut être que votre Bitmap est toujours sélectionné dans le pOutputMemDC quand il est détruit et l'un d'eux ou les deux ne peut être supprimé correctement. Ainsi des problèmes de mémoire pourraient commencer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top