3

高性能を実現するために、大きな CompatibleDC を作成し、その上に大きな画像を描画してから、画像の一部を他の DC に bitblt したいと考えています。

次のコードを使用して、互換性のあるメモリ DC を作成しています。しかし、rect が 5000*5000 などのように非常に大きくなると、作成された CompatibleDC が不安定になります。うまくいくこともあれば、失敗することもあります。私のコードに何か問題がありますか?

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);
}
4

3 に答える 3

2

大きな DC を作成してから、その一部を別の小さな DC にブリットする代わりに、宛先 DC と同じサイズ、または少なくともブリット先と同じサイズの DC を作成します。次に、コピーするサブセクションの (-x,-y) によってすべての描画コマンドをオフセットします。宛先がソースで (100,200)-(400,400) の場合、DC (300x200) を作成し、すべてを (-100,-200) オフセットします。

これには 2 つの大きな利点があります。まず、必要なメモリがはるかに小さくなります。第 2 に、GDI は描画操作を DC のサイズにクリップします (とにかく常にクリップします)。クリッピングの動作には CPU 時間がかかりますが、表示されないピクセルを描画しないことで節約される時間は、それを補って余りあるものです。

ここで、この大きな DC が画像 (JPEG など) のようなものである場合は、他の方法を検討する必要があります。多くの画像編集プログラムで使用される手法の 1 つは、画像をタイルに分割し、タイルをメモリ/ハードディスクとの間でページングすることです。各タイルは独自の DC であり、ターゲット DC を満たすのに十分なソース DC しかありません。ビュー ウィンドウが大きな画像上を移動するときに、ターゲットの四角形の外に移動したタイルをアンロードし、表示されたタイルをロードします。

于 2009-05-19T08:36:21.500 に答える
0

各5000x5000ピクセルの画像には約 100MBのRAM。PCのRAMの量によっては、これがすでに問題になっている可能性があります。

1GB以上のRAMがある場合、それはおそらく問題ではありません。この場合、メモリリークが発生している必要があります。割り当てられたビットマップはどこで解放しますか?あなたはブラシを実現していないようですが、ビットマップはどうですか?

スワップを増やしてもパフォーマンスが低下するため、役に立たないことに注意してください。

于 2009-05-19T08:04:09.910 に答える