Вопрос по c++ – Получить Pixel Color самый быстрый способ?

8

Я пытаюсь создать автокликер для приложения для Windows. Это работает хорошо, но невероятно медленно! Я в настоящее время использую метод "getPixel" который перезагружает массив каждый раз, когда он вызывается.

Вот мой текущий код:

<code>hdc = GetDC(HWND_DESKTOP);
bx = GetSystemMetrics(SM_CXSCREEN);
by = GetSystemMetrics(SM_CYSCREEN);
start_bx = (bx/2) - (MAX_WIDTH/2);
start_by = (by/2) - (MAX_HEIGHT/2);
end_bx = (bx/2) + (MAX_WIDTH/2);
end_by = (by/2) + (MAX_HEIGHT/2);

for(y=start_by; y<end_by; y+=10)
{   
    for(x=start_bx; x<end_bx; x+=10)
    {
        pixel = GetPixel(*hdc, x, y);
        if(pixel==RGB(255, 0, 0))
        {
            SetCursorPos(x,y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            Sleep(50);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            Sleep(25);
        }
    }
}
</code>

Так что, в основном, он просто сканирует диапазон пикселей на экране и запускает событие мыши, если обнаруживает красную кнопку.

Я знаю, что есть и другие способы получить цвет пикселя, например, bitblt. Но я провел некоторые исследования, и я не понимаю, как я должен это делать, чтобы сканировать массив цветов. Мне нужно что-то, что сканирует экран очень быстро, чтобы поймать кнопку.

Не могли бы вы мне помочь?

Благодарю.

Кстати, все мои вещи в теме. И, как я уже сказал, это хорошо работает с getPixel. я просто ищу лучший способ сделать это Manitoba
Это не работает хорошо - вы сказали, что это медленно. Без профилирования данных я привел лучшую причину, по которой это медленно. tenfour
Если этот код находится в бесконечном цикле, то проблема не вGetPixel, Это тот факт, что ваше приложение не позволяет другим приложениям занимать процессорное время. tenfour
Кстати, мой код находится в бесконечном цикле. Но я хочу использовать цветовую ловушку, а офсетную. Поэтому, когда я запускаю свой код, он просто заходит в цикл и проверяет наличие красной кнопки. Manitoba
Когда ваш код называется? в простое? когда пользователь двигает мышь? Существуют разные способы обнаружения красной кнопки, например, с помощью FindWindow (). Adriano Repetti

Ваш Ответ

2   ответа
1

что, если вы настаиваете на том, чтобы использовать этот метод, оптимизировать его не нужно. Как отмечали другие в комментариях, вам, вероятно, следует использовать другой метод для определения местоположения области, в которой нужно щелкнуть. Взгляните на использование FindWindow, например.

Если вы не хотите менять свой метод, то, по крайней мере, спите свою ветку немного после каждого полного сканирования экрана.

Кнопка, которую вы хотите нажать, вероятно, имеет собственный дескриптор окна. Попробуйте использовать программу проверки окон, такую как Spy ++, чтобы найти дескриптор окна того, на что вы хотите щелкнуть, и вы, вероятно, сможете найти этот конкретный элемент с помощью некоторого умного кода.
Здравствуйте, вы можете рассказать мне больше о Findwindow? Я использую это так:mhwnd = FindWindow(NULL, "Application Window Name"); hdc = GetDC(mhwnd); Что дальше? Manitoba
11

HDC hdc, hdcTemp;
RECT rect;
BYTE* bitPointer;
int x, y;
int red, green, blue, alpha;

while(true)
{
    hdc = GetDC(HWND_DESKTOP);
    GetWindowRect(hWND_Desktop, &rect);
            int MAX_WIDTH = rect.right;
        int MAX_HEIGHT = rect.bottom;

    hdcTemp = CreateCompatibleDC(hdc);
    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = MAX_WIDTH;
    bitmap.bmiHeader.biHeight = MAX_HEIGHT;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 32;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap2);
    BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY);

    for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4)
    {
        red = (int)bitPointer[i];
        green = (int)bitPointer[i+1];
        blue = (int)bitPointer[i+2];
        alpha = (int)bitPointer[i+3];

        x = i / (4 * MAX_HEIGHT);
        y = i / (4 * MAX_WIDTH);

        if (red == 255 && green == 0 && blue == 0)
        {
            SetCursorPos(x,y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            Sleep(50);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            Sleep(25);
        }
    }
}

Я надеюсь, что это может помочь кому-то еще.

Хорошая работа, но есть кое-что, чего я не понимаю. Зачем учитывать байт, назначенный альфа-компоненту пикселя? Потому что, поскольку это скриншот, значение альфа всегда будет 255, верно? Итак, не лучше ли сделать параметр biBitCount равным 24?
X а такжеY расположение пикселя, который просматривается. Они бесполезны, если только вы не хотите выполнить действие с этим пикселем. Если его цвет полностью красный, он установит мышь на этот пиксель и сделает щелчок левой кнопкой мыши. Manitoba
Вы совершенно правы. Часть Aplha бесполезна. Manitoba
GetWindowRect с дескриптором HWND_DESKTOP возвращает FALSE. нужно добавить hWND_Desktop = GetDesktopWindow ()? или используйте вместо этого GetSystemMetrics ().
это проверка каждого пикселя? Я не понимаю ваших назначений по x и y.

Похожие вопросы