2015-05-19 3 views
-1

Итак, я ищу способ прочитать цвет пикселя экрана в коде C.
Я уже нашел реализацию в C для * nix (которая использует библиотеку X11/Xlib, которая, как я понял, только для систем * nix), и я пробовал код на машине linux, и он работал довольно быстро (он читает 8K пикселей за 1 секунду).
Вот код в C, что я нашел и раздвоенный:C - как читать цвет пикселя экрана (FAST)? (в Windows)

#include <X11/Xlib.h> 
void get_pixel_color (Display *d, int x, int y, XColor *color) 
{ 
    XImage *image; 
    image = XGetImage (d, RootWindow (d, DefaultScreen (d)), x, y, 1, 1,  AllPlanes, XYPixmap); 
    color->pixel = XGetPixel (image, 0, 0); 
    XFree (image); 
    XQueryColor (d, DefaultColormap(d, DefaultScreen (d)), color); 
} 

// Your code 
XColor c; 
    get_pixel_color (display, 30, 40, &c); 
    printf ("%d %d %d\n", c.red, c.green, c.blue); 

И я искал аналогичное решение для Windows, а также.
я наткнулся на этот код (я поставил код о чтении экранный пиксель в «для» петли):

FARPROC pGetPixel; 

HINSTANCE _hGDI = LoadLibrary("gdi32.dll"); 
if(_hGDI) 
{ 
    pGetPixel = GetProcAddress(_hGDI, "GetPixel"); 

    HDC _hdc = GetDC(NULL); 
if(_hdc) 
{ 
    int i; 
    int _red; 
    int _green; 
    int _blue; 
    COLORREF _color; 
    ReleaseDC(NULL, _hdc); 
    for (i=0;i<8000;i++) 
    { 
     _color = (*pGetPixel) (_hdc, 30 ,40); 

     _red = GetRValue(_color); 
     _green = GetGValue(_color); 
     _blue = GetBValue(_color); 


    } 
    ReleaseDC(NULL, _hdc);  
    printf("Red: %d, Green: %d, Blue: %d", _red, _green, _blue); 
} 
FreeLibrary(_hGDI); 

(с использованием gdi32.dll и windows.h ...)
и тому «для» части кода (где мы читаем 8K пикселей) работает ALOT медленнее, чем решение в C. , для завершения по сравнению с 1 секундой для X11/Xlib.h требуется 15 секунд!

Итак, как я могу сделать это лучше? или есть ли какая-нибудь другая лучшая реализация FASTER для чтения пиксельных цветов с помощью кода C на компьютере с Windows?

Спасибо заранее!

+2

Hmya, пропускная способность 32KB/sec не так много, чтобы хвастаться. Windows требует, чтобы программисты были более умными читателями, книга Петцольда хорошо объясняет BitBlt(). –

+0

Сколько пикселей вы пытаетесь прочитать здесь? Всего 1, или вы собираетесь проверять целую кучу? Если целая группа, getPixel, вероятно, не способ сделать это, а не то, что захватывает весь экран текстуры сразу. –

+0

Да, я пытаюсь читать кучу ... Как я показал, решение * nix может читать много пикселей за 1 секунду, в то время как решение для Windows очень медленное ... Любые предложения, другие решения или ресурсы? Я искал лучшее решение в Windows некоторое время, и я просто не мог его найти. – Matan

ответ

0

Я предлагаю использовать loop unwinding. В принципе, то, что это делает выполнить несколько циклов вашего цикла в одной итерации:

// Loop the equivalent of `n` cycles, ignoring the least significant bit 
for (unsigned int i = 0; i < (n & ~0x01); i += 2) 
{ 
    do_some_operation(i); 
    do_some_operation(i + 1); 
} 

// Perform the last cycle manually, if one needs to be completed 
if (n & 0x01) 
{ 
    do_some_operation(n - 1); 
} 

В этом коде цикл игнорирует наименьший значащий бит n (который определяет соотношение n), так что мы в безопасности для увеличения i на 2 и выполнить эквивалент 2 тактов всего за 1 цикл, что означает, что этот цикл ~ в 2 раза быстрее, чем обычный цикл for (unsigned int i = 0; i < n; i++). Итоговый отчет if проверяет соотношение n. Если n нечетно, выполняется последний цикл цикла.

Конечно, это может быть переопределено для увеличения i более чем на 2, но это будет становиться все более сложным. Существует также альтернатива этому, Duff's Device. Это в основном та же идея, но использует блок switch/case.

+0

Я не думаю, что это проблема на уровне цикла. вместо этого это уровень драйвера неэффективный способ получения информации. Если OP будет извлекать много пикселей с экрана, ему может быть лучше скрыть экран до текстуры, а затем посмотреть на это. –

+0

Я подумал о том, чтобы сделать снимок, а затем проанализировать его, но весь процесс очень медленный, так как ... просто картинка составляет около 3 ~ 4 секунды или около того. @Levi - функция «pGetPixel» - это та, которая требует много времени, чтобы закончить ... Я ищу совершенно новую реализацию или способ прочитать кучу цветов пикселя экрана. Почему X11/Xlib решение так быстро по сравнению с Window's? – Matan

+0

Почему X11/Xlib быстрее? Levi

0

После многих тестов я обнаружил, что примерно/ничего/вы делаете, чтобы считывать пиксели с экрана в окнах, используя GDI, занимает ~ 16 мс (или около 1 кадра) независимо от того, читает ли он один пиксель или читает даже небольшая область с BitBlt. Кажется, не существует четкого решения. Я буду экспериментировать с медиа-библиотеками, чтобы узнать, могу ли я где-нибудь добраться, но в Интернете почти уверен, что делать что-либо подобное в Windows - это просто ужасный беспорядок, и действительно нужно сделать ужасные вещи, чтобы делать такие вещи, как VNC или Fraps.