首先用GetPixel()去获取整个屏幕的像素,比如1920*1080的分辨率,那估计要等"一个世纪",
有木有其他办法呢?答案是肯定的。
我用GetDIBits()函数代替了GetPixel()函数。具体代码如下
void CTouchDlg::GetPixelColor()
{
// TODO: 在此处添加实现代码.
CWnd *pWnd = FindWindow(NULL, L"Touch.exe");
HWND hWnd = pWnd->GetSafeHwnd();
HDC hDesktopDC = ::GetDC(hWnd);
HDC hTmpDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDesktopDC, scWidth, scHeight);
SelectObject(hTmpDC, hBmp);
BitBlt(hTmpDC, 0, 0, scWidth, scHeight, hDesktopDC, 0, 0, SRCCOPY);
DeleteObject(hTmpDC);
BITMAP bm;
PBITMAPINFO bmpInf;
if (GetObject(hBmp, sizeof(bm), &bm) == 0)
{
::ReleaseDC(NULL, hDesktopDC);
return;
}
int nPaletteSize = 0;
if (bm.bmBitsPixel < 16)
nPaletteSize = (int)pow(2, bm.bmBitsPixel);
bmpInf = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD)*nPaletteSize + (bm.bmWidth + 7) / 8 * bm.bmHeight*bm.bmBitsPixel);
BYTE* buf = ((BYTE*)bmpInf) +
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD)*nPaletteSize;
//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) / 8 * bm.bmHeight*bm.bmBitsPixel;
//-----------------------------------------------
if (!::GetDIBits(hDesktopDC, hBmp, 0, (UINT)bm.bmHeight, buf, bmpInf, DIB_RGB_COLORS))
{
::ReleaseDC(NULL, hDesktopDC);
LocalFree(bmpInf);
return;
}
::ReleaseDC(NULL, hDesktopDC);
CClientDC dc(this);
CPoint point;
int nOffset;
BYTE r, g, b;
int nWidth = bm.bmWidth*bm.bmBitsPixel / 8;
nWidth = ((nWidth + 3) / 4) * 4; //4字节对齐
if (bmpInf->bmiHeader.biBitCount == 8)
{
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
RGBQUAD rgbQ;
rgbQ = bmpInf->bmiColors[buf[i*nWidth + j]];
if (rgbQ.rgbBlue == 255 && rgbQ.rgbGreen == 255 && rgbQ.rgbRed == 255)
{
point.x = j;
point.y = i - 1;
m_v_point_start.push_back(point);
dc.SetPixel(j, bm.bmHeight - i - 1, RGB(0, 255, 0));
}
}
}
}
else if (bmpInf->bmiHeader.biBitCount == 16)
{
for (int i = 0; i < bm.bmHeight; i++)
{
nOffset = i * nWidth;
for (int j = 0; j < bm.bmWidth; j++)
{
b = buf[nOffset + j * 2] & 0x1F;
g = buf[nOffset + j * 2] >> 5;
g |= (buf[nOffset + j * 2 + 1] & 0x03) << 3;
r = (buf[nOffset + j * 2 + 1] >> 2) & 0x1F;
r *= 8;
b *= 8;
g *= 8;
if (b == 255 && g == 255 && r == 255)
{
point.x = j;
point.y = i - 1;
m_v_point_start.push_back(point);
dc.SetPixel(j, bm.bmHeight - i - 1, RGB(0, 255, 0));
}
}
}
}
else if (bmpInf->bmiHeader.biBitCount == 24)
{
for (int i = 0; i < bm.bmHeight; i++)
{
nOffset = i * nWidth;
for (int j = 0; j < bm.bmWidth; j++)
{
b = buf[nOffset + j * 3];
g = buf[nOffset + j * 3 + 1];
r = buf[nOffset + j * 3 + 2];
if (b == 255 && g == 255 && r == 255)
{
point.x = j;
point.y = i - 1;
m_v_point_start.push_back(point);
dc.SetPixel(j, bm.bmHeight - i - 1, RGB(0, 255, 0));
}
}
}
}
else if (bmpInf->bmiHeader.biBitCount == 32)
{
for (int i = 0; i < bm.bmHeight; i++)
{
nOffset = i * nWidth;
for (int j = 0; j < bm.bmWidth; j++)
{
b = buf[nOffset + j * 4];
g = buf[nOffset + j * 4 + 1];
r = buf[nOffset + j * 4 + 2];
if (b == 255 && g == 255 && r == 255)
{
point.x = j;
point.y = i-1;
m_v_point_start.push_back(point);
dc.SetPixel(j, bm.bmHeight - i-1, RGB(0, 255, 0));
}
}
}
}
DeleteObject(hBmp);
LocalFree(bmpInf);
}
这段代码可以直接使用,要注意的地方是dc.SetPixel(j, bm.bmHeight - i-1, RGB(0, 255, 0));着色的时候坐标注意下就OK了。
遇到了此类问题,记录下来。嘿嘿