该函数的目的是通过指定像素颜色查找像素的坐标。该函数现在处理屏幕分辨率的 1/20,这个速度至少是可以忍受的。使用这个系统,准确性会受到很大影响。
POINT FindColor(BYTE r, BYTE g, BYTE b) {
HDC hDC = GetDC(NULL);
int width = GetDeviceCaps(hDC, HORZRES);
int height = GetDeviceCaps(hDC, VERTRES);
int xStep = width / 20;
int yStep = height / 20;
for (int x = 0; x < width; x += xStep) {
for (int y = 0; y < height; y += yStep) {
COLORREF color = GetPixel(hDC, x, y);
BYTE pixelR = GetRValue(color);
BYTE pixelG = GetGValue(color);
BYTE pixelB = GetBValue(color);
if (pixelR == r && pixelG == g && pixelB == b) {
ReleaseDC(NULL, hDC);
POINT p;
p.x = x;
p.y = y;
return p;
}
}
}
ReleaseDC(NULL, hDC);
POINT p = { -1, -1 };
return p;
}
目标是处理每个像素,但找到颜色需要超过 1 秒。
可能最好的解决方案是通过大量线程,但我不知道如何形式化它。
问题是,如何优化代码,使代码处理所有像素进行检查,以确保准确性,但查找颜色的速度约为 1 秒?
以下代码只需 58 毫秒即可检查整个图像,无需平铺或单独的线程。
HBITMAP GetScreenBmp(HDC hdc) {
// Get screen dimensions
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
// Create compatible DC, create a compatible bitmap and copy the screen
using BitBlt()
HDC hCaptureDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
HGDIOBJ hOld = SelectObject(hCaptureDC, hBitmap);
BOOL bOK = BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hdc, 0, 0, SRCCOPY | CAPTUREBLT);
SelectObject(hCaptureDC, hOld); // always select the previously selected object once done
DeleteDC(hCaptureDC);
return hBitmap;
}
POINT FindColor(BYTE r, BYTE g, BYTE b) {
const COLORREF findColorRef = RGB(r, g, b);
HDC hDC = GetDC(NULL);
int width = GetDeviceCaps(hDC, HORZRES);
int height = GetDeviceCaps(hDC, VERTRES);
HBITMAP hBitmap = GetScreenBmp(hDC);
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the BITMAPINFO structure from the bitmap
if (0 == GetDIBits(hDC, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS)) {
cout << "error" << endl;
}
// create the bitmap buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
// Better do this here - the original bitmap might have BI_BITFILEDS, which makes it
// necessary to read the color table - you might not want this.
MyBMInfo.bmiHeader.biCompression = BI_RGB;
// get the actual bitmap buffer
if (0 == GetDIBits(hDC, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS)) {
cout << "error2" << endl;
}
const int bufferSize = width * height*3;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
if ((lpPixels[4 * ((y * width) + x) + 2] == r) && (lpPixels[4 * ((y * width) + x) + 1] == g) && (lpPixels[4 * ((y * width) + x) ] == b))
{
ReleaseDC(NULL, hDC);
POINT p;
p.x = x;
p.y = y;
return p;
}
}
}
ReleaseDC(NULL, hDC);
POINT p = { -1, -1
};
return p;
}