C - 如何读取屏幕像素的颜色(FAST)? (在Windows中)

时间:2015-05-19 23:02:51

标签: c colors pixel xlib

所以我正在寻找一种在C代码中读取屏幕像素颜色的方法 我已经在C for for nix中找到了实现(它使用的是X11 / Xlib库,据我所知仅适用于* nix系统)而且我在linux机器上尝试了代码,并且运行速度非常快(它读取的像素为8K)约1秒) 这是我发现并分叉的C中的代码:

#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的等效解决方案 我遇到了这段代码(我把关于读取屏幕像素的代码放在'for'循环中):

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 ...)
并且代码的'for'部分(我们读取8K像素)比C中的解决方案运行得慢。 使用X11 / Xlib.h库需要15秒才能完成!

那么,我怎样才能让它变得更好?或者还有其他更好更快的实现,用Windows机器中的C代码读取像素的颜色?

提前致谢!

2 个答案:

答案 0 :(得分: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并执行等效在1个周期内的2个周期,意味着这个环比传统的for (unsigned int i = 0; i < n; i++)环快〜2倍。最终if语句检查n的奇偶校验。如果n为奇数,则执行循环的最后一个循环。

当然,这可以重新实现,使i增加2以上,但这会变得越来越复杂。还有另一种选择,Duff's Device。这基本上是相同的想法,但使用switch / case块。

答案 1 :(得分:0)

经过多次测试后,我发现使用GDI在窗口中读取像素的几乎/任何/你需要大约16ms(或大约1帧),无论是读取单个像素还是读取均匀BitBlt的一个小区域。似乎没有任何明确的解决方案。我将尝试使用媒体库来查看我是否可以到达任何地方,但是互联网非常确定在Windows中做这样的事情只是一个非常糟糕的事情,而且做VNC或Fraps之类的事情真的很糟糕。