我想绘制网格,如下图所示。
我知道通过绘制6条垂直和水平线而不是6 x 6小矩形来绘制它的技巧。
但是如果我想要更小的缩放(缩放以查看图片),那么线条很多。例如,假设我的视图窗口大小为800 x 600并且查看大小为400 x 300的图片(因此放大为2)。将有400 x 300矩形,大小为2 x 2(每个矩形代表一个像素)。
如果我绘制每个单元格(在一个循环中,比如400 x 300次),它就会很慢(当我移动窗口时......)。 使用这个技巧解决了这个问题。
我仍然很好奇是否有更好的方法在winapi,GDI(+)中完成这项任务。例如,像DrawGrid(HDC hdc, int x, int y, int numOfCellsH, int numOfCellsV)
?
另一个问题是:如果我没有调整大小,移动窗口或者我不更改放大,则不会更改网格。因此,即使我连续更新图片(捕获屏幕),重绘网格也是必要的。但是我使用StretchBlt
和BitBlt
来捕获屏幕(到内存DC然后是窗口的hdc),如果我没有在内存DC中重绘网格,那么网格将消失。有没有办法让网格粘在那里并更新屏幕截图的位图?
ps:这不是一个真正的问题。由于我想在缩放不小于10时绘制网格(因此每个单元的大小为10 x 10或更大)。在这种情况下,最多可以绘制100 + 100 = 200行并且速度很快。如果有更快的方法,我只是好奇。
答案 0 :(得分: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);
答案 1 :(得分:0)
一般来说,这类图形操作的主要限制因素是填充率和函数调用次数。
填充率是机器更改像素值的速度。通常,blits(复制矩形区域)非常快,因为它们经过高度优化并设计为以缓存友好顺序触摸内存。但是一个blit会触及该区域的所有像素。如果你要透支或者大多数像素并不真的需要改变,那么只绘制你需要的像素可能更有效率,即使它不像缓存那样友好。
如果你通过制作n个东西来绘制n个原语,那么当
您的“技巧”演示了这两种优化。绘制20行是比100个矩形少的调用,它触及的像素少得多。随着窗口的增长或网格尺寸的减小,线条逼近将在调用次数和触摸的像素中线性增加,而矩形方法将增长为n ^ 2.
在触摸最小像素数时,我认为你不能做得更好。但是,如果您绘制了很多行,我认为函数调用的数量可能成为一个因素。我不知道GDI +,但在简单的GDI中,有Polyline
和PolyPolyline
这样的函数可以让你在一次调用中绘制几行。