0

So actually i got a very fast and nice code from "Vodemki" in here - Get Pixel color fastest way?

But only problem it scans the whole image while i need to scan only my current mouse position

Here's the code -

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

I'm not familiar with BitBlt, So if anyone can help me modify that code i'll appreciate it

Thanks!

Community
  • 1
  • 1
Tom Weiss
  • 11
  • 4
  • Couldn't you do something like throw the BitMap into a Texture in OpenGL (size of screen) then map the touch cords to the OpenGL cords and Whala you search for the part of the texture at that point? – Jackie Jun 25 '13 at 21:09
  • Can you show me an example? I don't really understand... BTW I'm getting the screenshot from directx full screen application – Tom Weiss Jun 25 '13 at 21:10
  • I don't know how easy it would be to throw one together but I can try to explain my "theory" a little more. So the BMP has dimensions and those dimensions are scaled to be screen size in this scenario. So can't you just read up to a certain byte position in the data based on the X/y of the touch. Essentially normalizing both the BMP pixel cords and the touch (this is pretty much done for you depending on the rotation of the bmp). That way even if you were streaming you would only have to "read up to" the touch cords. – Jackie Jun 25 '13 at 21:37
  • P.S. I know nothing about directX I use OpenGL but I would assume from what I have read the concepts are similar (you have primitives and textures and shaders) so I think it should be similar. – Jackie Jun 25 '13 at 21:38
  • Might help... http://stackoverflow.com/questions/7033801/slimdx-directx9-c-how-to-access-pixel-data-in-a-texture – Jackie Jun 25 '13 at 21:39
  • Actually, using the code i posted i can access the DirectX if i get the right window handle. But i don't really want to make it the "hard" way... I just want to get the code to scan the current mouse x & y color as RGB. Thanks... – Tom Weiss Jun 25 '13 at 21:52
  • Right but that is what I am trying to say you can get it by converting the pixel location to the location that you touch. All pixels in DirectX are stored in a big array, so if you know which entry in that array matched the entry in for what you touched all you have to do is find the value pointed at by that array entry. Why do you have to read the whole buffer? – Jackie Jun 25 '13 at 21:55
  • Actually I don't need to read the whole buffer, I just need 1 pixel. Maybe I just need to use some math and change the cords... – Tom Weiss Jun 25 '13 at 21:58
  • It would be something like bitPointer[(x*2+MAXRGBA)+y+SELECTEDRGB] with selected RGB being the color you are looking for (or Alpha). – Jackie Jun 25 '13 at 21:59
  • I'll try some options, Thanks for your help. – Tom Weiss Jun 25 '13 at 22:01
  • Anyone here can help me? Didn't made it yet... – Tom Weiss Jun 29 '13 at 16:01
  • did you try what I said bitPointer[(x*2+MAXRGBA)+y+SELECTEDRGBA] – Jackie Jun 29 '13 at 21:22
  • Still don't work, It looks like i don't get the right colors... – Tom Weiss Jun 30 '13 at 12:20

1 Answers1

1

Alright I made it finally. I still got problem with the timing, makes my puter very slow... I'll work for it later...

Here's the code -

//Globals

int sX, sY, x, y;

BYTE* sData = 0;

POINT cursorPos;

HDC hScreen;
HDC hdcMem;
HBITMAP hBitmap;
HGDIOBJ hOld;


void PixelFunction();   // Get the pixel rgb function

int main()
{
    PixelFunction();

    ReleaseDC(NULL, hScreen);
    DeleteDC(hdcMem);

    return 0;
}


void PixelFunction()
{
    int Red, Green, Blue;

    hScreen = GetDC(NULL);

    sX = GetDeviceCaps(hScreen, HORZRES);
    sY = GetDeviceCaps(hScreen, VERTRES);

    hdcMem = CreateCompatibleDC (hScreen);
    hBitmap = CreateCompatibleBitmap(hScreen, sX, sY);

    BITMAPINFOHEADER bm = {0};
    bm.biSize = sizeof(BITMAPINFOHEADER);
    bm.biPlanes = 1;
    bm.biBitCount = 32;
    bm.biWidth = sX;
    bm.biHeight = -sY;
    bm.biCompression = BI_RGB;
    bm.biSizeImage = 0; // 3 * sX * sY;

    while (1) {

        hOld = SelectObject(hdcMem, hBitmap);
        BitBlt(hdcMem, 0, 0, sX, sY, hScreen, 0, 0, SRCCOPY);
        SelectObject(hdcMem, hOld);

        free(sData);
        sData = (BYTE*)malloc(4 * sX * sY);

        GetDIBits(hdcMem, hBitmap, 0, sY, sData, (BITMAPINFO*)&bm, DIB_RGB_COLORS);

        GetCursorPos(&cursorPos);
        x = cursorPos.x;
        y = cursorPos.y;

        Red = sData[4 * ( (y * sX) + x) +2];
        Green = sData[4 * ( ( y * sX) + x) +1];
        Blue = sData[4 * ( (y * sX) + x)];

        // Check for color
        if (Red == 255 && Green == 0 && Blue == 0) {
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            Sleep(5);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }
        Sleep(10);
    }
}

Hope it helped!

Tom Weiss
  • 11
  • 4
  • Shouldn't the free be at the end of the loop? What about the last one is that ever freed? – Jackie Jul 01 '13 at 16:53
  • Could probably also short circuit if x and y = previous ones. NM forgot you are looping here waiting for an event. But don't you just look for these values when there is a click? Why do you need this loop? Why not just process data when you get a click even? I am not good with C# (only C and C++) so I am not sure. – Jackie Jul 01 '13 at 16:56