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

Я пытаюсь создать автокликер для приложения для 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. Но я провел некоторые исследования, и я не понимаю, как я должен это делать, чтобы сканировать массив цветов. Мне нужно что-то, что сканирует экран очень быстро, чтобы поймать кнопку.

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

Благодарю.

 Manitoba09 мая 2012 г., 14:13
Кстати, мой код находится в бесконечном цикле. Но я хочу использовать цветовую ловушку, а офсетную. Поэтому, когда я запускаю свой код, он просто заходит в цикл и проверяет наличие красной кнопки.
 Manitoba09 мая 2012 г., 14:19
Кстати, все мои вещи в теме. И, как я уже сказал, это хорошо работает с getPixel. я просто ищу лучший способ сделать это
 Adriano Repetti09 мая 2012 г., 14:08
Когда ваш код называется? в простое? когда пользователь двигает мышь? Существуют разные способы обнаружения красной кнопки, например, с помощью FindWindow ().
 tenfour09 мая 2012 г., 14:24
Это не работает хорошо - вы сказали, что это медленно. Без профилирования данных я привел лучшую причину, по которой это медленно.
 tenfour09 мая 2012 г., 14:15
Если этот код находится в бесконечном цикле, то проблема не вGetPixel, Это тот факт, что ваше приложение не позволяет другим приложениям занимать процессорное время.

Ответы на вопрос(2)

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

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

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

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);
        }
    }
}

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

 19 апр. 2014 г., 18:49
Хорошая работа, но есть кое-что, чего я не понимаю. Зачем учитывать байт, назначенный альфа-компоненту пикселя? Потому что, поскольку это скриншот, значение альфа всегда будет 255, верно? Итак, не лучше ли сделать параметр biBitCount равным 24?
 Manitoba27 февр. 2014 г., 09:59
X а такжеY расположение пикселя, который просматривается. Они бесполезны, если только вы не хотите выполнить действие с этим пикселем. Если его цвет полностью красный, он установит мышь на этот пиксель и сделает щелчок левой кнопкой мыши.
 Manitoba19 апр. 2014 г., 20:38
Вы совершенно правы. Часть Aplha бесполезна.
 24 июн. 2017 г., 09:42
GetWindowRect с дескриптором HWND_DESKTOP возвращает FALSE. нужно добавить hWND_Desktop = GetDesktopWindow ()? или используйте вместо этого GetSystemMetrics ().
 27 февр. 2014 г., 02:22
это проверка каждого пикселя? Я не понимаю ваших назначений по x и y.

Ваш ответ на вопрос