我想绘制网格,如下图所示。
我知道一个技巧,通过绘制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的时候绘制网格(所以每个单元格的大小都是10x10或更大)。在这种情况下,最多有100 + 100 = 200条线要绘制,而且速度很快。我只是好奇是否有更快的方法。
发布于 2012-09-07 12:39:00
您是否考虑过使用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-07 16:29:24
一般来说,这些类型的图形操作的主要限制因素是填充率和函数调用的数量。
填充速率是机器更改像素值的速度。一般来说,blits (复制矩形区域)非常快,因为它们经过高度优化,并设计为以缓存友好的顺序访问内存。但是blit会触及该区域中的所有像素。如果你打算透支,或者那些像素中的大部分不需要改变,那么只绘制你需要的像素可能会更有效,即使这并不是缓存友好的。
如果您通过制作n个事物来绘制n个原语,那么当n变大时,这可能是一个限制因素,并且寻找一个允许您一次绘制多条(或全部)线的API调用可能是有意义的。
您的“技巧”演示了这两个优化。绘制20条线比绘制100个矩形的调用少得多,而且它涉及的像素要少得多。随着窗口的增大或网格大小的减小,线方法在调用次数和接触的像素方面都将线性增加,而rectangle方法将增长为n^2。
当涉及到最小像素数时,我不认为你能做得更好。但我认为,如果你画了很多线,函数调用的数量可能会成为一个因素。我不知道GDI+,但在普通的GDI中,有像Polyline
和PolyPolyline
这样的函数可以让你在一次调用中画出几条线。
https://stackoverflow.com/questions/12315724
复制相似问题