1

下の写真のようにグリッドを描きたいです。ここに画像の説明を入力してください

6 x 6の小さな長方形ではなく、6本の垂直線と水平線を描くことでこれを描くコツを知っています。

しかし、ズームを小さくしたい場合(画像を表示するためのズーム)、線はたくさんあります。たとえば、ビューウィンドウのサイズが800 x 600で、サイズが400 x 300の画像を表示しているとします(ズームインは2です)。サイズが2x2の400x300の長方形があります(各長方形はピクセルを表します)。

各セルを(ループで、たとえば400 x 300回)描画すると、非常に遅くなります(ウィンドウを移動したとき...)。トリックを使用すると、問題が解決します。

Winapiでこのタスクを実行するためのより良い方法であるGDI(+)があるかどうか、私はまだ興味があります。たとえば、DrawGrid(HDC hdc, int x, int y, int numOfCellsH, int numOfCellsV)?のような関数

さらに質問があります。サイズを変更しない、ウィンドウを移動しない、またはズームインを変更しない場合、グリッドは変更されません。そのため、画像を継続的に更新しても(キャプチャ画面)、グリッドを再描画する必要はありません。しかし、画面をキャプチャするために(メモリDCに、次にウィンドウのhdcに)を使用StretchBltBitBltます。メモリDCにグリッドを再描画しなかった場合、グリッドは消えます。グリッドをそこに固定し、スクリーンキャプチャのビットマップを更新する方法はありますか?

ps:これは実際の問題ではありません。ズームが10以上のときにグリッドを描画したいので(したがって、各セルのサイズは10 x 10以上です)。この場合、描画する線は最大100 + 100 = 200であり、高速です。もっと速い方法があるかどうか私はただ興味があります。

4

2 に答える 2

0

CreateDIBSectionの使用を検討しましたか?これにより、R、G、B値をすばやく操作できるようにポインターが可能になります。たとえば、次のように256x256x24ビットマップを作成し、64ピクセル間隔で緑色の正方形をペイントします。

BITMAPINFO BI = {0};
BITMAPINFOHEADER &BIH = BI.bmiHeader;
BIH.biSize = sizeof(BITMAPINFOHEADER);
BIH.biBitCount  = 24;
BIH.biWidth     = 256;
BIH.biHeight    = 256;
BIH.biPlanes    = 1;
LPBYTE pBits = NULL;
HBITMAP hBitmap = CreateDIBSection(NULL, &BI, DIB_RGB_COLORS, (void**) &pBits, NULL, 0);
LPBYTE pDst = pBits;
for (int y = 0; y < 256; y++)
{
    for (int x = 0; x < 256; x++)
    {
        BYTE R = 0;
        BYTE G = 0;
        BYTE B = 0;
        if (x % 64 == 0) G = 255;
        if (y % 64 == 0) G = 255;
        *pDst++ = B;
        *pDst++ = G;
        *pDst++ = R;
    }
}
HDC hMemDC = CreateCompatibleDC(NULL);
HGDIOBJ hOld = SelectObject(hMemDC, hBitmap);
BitBlt(hdc, 0, 0, 256, 256, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOld);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
于 2012-09-07T12:38:59.967 に答える
0

一般的に言えば、これらの種類のグラフィック操作の主な制限要因は、フィル レートと関数呼び出しの数です。

フィルレートは、マシンがピクセル値を変更できる速さです。一般に、ブリット (長方形の領域のコピー) は非常に高速です。これは、高度に最適化されており、キャッシュに適した順序でメモリにアクセスするように設計されているためです。しかし、ブリットはその領域のすべてのピクセルに触れます。オーバードローする場合、またはそれらのピクセルのほとんどを実際に変更する必要がない場合は、必要なピクセルだけを描画する方が効率的である可能性があります (キャッシュ フレンドリーではない場合でも)。

n 個の物を作成して n 個のプリミティブを描画している場合、n が大きくなるため、それが制限要因になる可能性があり、一度に複数 (またはすべて) の線を描画できる API 呼び出しを探すのが理にかなっている可能性があります。

あなたの「トリック」は、これらの最適化の両方を示しています。20 本の線を描画することは、100 個の四角形を描画するよりも呼び出しが少なく、触れるピクセルもはるかに少なくなります。また、ウィンドウが大きくなったり、グリッド サイズが小さくなったりすると、ライン アプローチは呼び出し回数とタッチされたピクセルの両方で直線的に増加しますが、長方形メソッドは n^2 として大きくなります。

最小ピクセル数に触れることに関しては、これ以上のことはできないと思います。しかし、非常に多くの線を描画している場合、関数呼び出しの数が要因になる可能性があると思います。GDI+ はわかりませんが、普通の GDI には、Polylineやのような関数がありPolyPolyline、1 回の呼び出しで複数の線を描画できます。

于 2012-09-07T16:29:23.813 に答える