views:

113

answers:

3

Ok, I'm trying to make a program that finds the position of a colored pixel within the desktop. To do this I make a screenshot of the desktop then go through the pixels and search for the one that has the matching RGB as i need. The only problem is that my program returs strange coordonates X,Y for the found pixel...

#include <stdio.h>
#include <windows.h>
#include <atlimage.h>
#include <iostream>
using namespace std;
struct rgbcolor{
    int red;
    int green;
    int blue;} myColor;
struct point{
        int x;
        int y;
    };
point SearchPixel(int r,int g, int b){
    CImage bitmapzor;
    bitmapzor.Load(("C:\\1.bmp"));
    COLORREF PixColor=0; //This is a color data
    int R=0,G=0,B=0; //These are the channel values
    BYTE* byteptr = (BYTE*)bitmapzor.GetBits();
    int ok=0;
    int pitch = bitmapzor.GetPitch(); //This is a pointer offset to get new line of the bitmap
    //Go through every pixel and compare the RGB code
    for (int i=0; i<bitmapzor.GetWidth();i++)
        for (int j=0; j<bitmapzor.GetHeight();j++)
        {
            B= *(byteptr+pitch*j+3*i);
            G= *(byteptr+pitch*j+3*i+1);
            R= *(byteptr+pitch*j+3*i+2);       
            if(R==r&&G==g&&B==b)
            { point p;
              p.x=i;
              p.y=j;
              cout<<"First pixel found at:\n X:"<<p.x<<"\n Y:"<<p.y<<"\n-----------------\n";
              return p; 
            }
        }
    bitmapzor.Destroy(); //destroy the bitmap
    point p;
    p.x=-1;
    p.y=-1;
    cout<<"Pixel not found!\n";
    return p;

}

bool ScreenCapture(int x, int y, int width, int height, char *filename){
   // get a DC compat. w/ the screen
   HDC hDc = CreateCompatibleDC(0);    

   // make a bmp in memory to store the capture in
   HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height);   

   // join em up
   SelectObject(hDc, hBmp);   

   // copy from the screen to my bitmap
    BitBlt(hDc, 0, 0, width, height, GetDC(0), x, y, SRCCOPY); 
       CImage image;
        image.Attach(hBmp);
        image.Save(("C:\\1.bmp"), Gdiplus::ImageFormatBMP);
      SearchPixel(myColor.red,myColor.green,myColor.blue);

   // free the bitmap memory
   DeleteObject(hBmp);  

   return 1;
   }

int main()
{   //RGB for the searched color
    myColor.red=200;
    myColor.green=191;
    myColor.blue=231;

    int count=0;
    while(true){
        ScreenCapture(0, 0, 1366, 768, "c:\\1.bmp");
            count++;
        cout<<"Number of searches:"<<count<<"\n\n";
        Sleep(500);
    }
   system("pause");
   return 0;    
}
A: 

Well, this code could be simplified quite a lot, but first I'd suggest you try a much, much simpler case, like finding a known integer in a small array of integers. Once you have that working, move up to more complex cases.

EDIT:
You have enough knowledge to do this? Cristy, please don't take this the wrong way, but of all the programmers I've had to deal with, the worst have been the ones who thought they had nothing to learn. I didn't actually look for the bug in your code because your code is overcomplicated, and if you had gone from simple to complex when building it, you would have caught your error a lot sooner.

Beta
I don't understand? I've been learning C++ for 2 years, I've already made a C++ game so I have enough knowladge to do this.
Cristy
Actually the code is a simple as it can get. This is the fastest method to get a pixel color (GetPixel is very slow) , and the searching algorithm is simply a linear search.I wrote in my answear, the error I made was because when I used example bmps (without screenshot) they were 24bits, and when i used screeshots they were 32bits so the position of each pixel would be stored in a diffrent place in the memory (diffrent pointers) .Trust me, I've done more searching algorithms then you may have seen , each for duzin of times... (heap sort, liniear sort, bubble sort, quick sort, etc...) Thanks!
Cristy
@Cristy: really? Because I was able to simplify it quite a lot (using the same method to get a pixel color). But hey, I'll trust you, you clearly have nothing to learn, and I'm pleased to meet someone who has done all the search algorithms I've done (A*, simplex, simulated annealing, least-action, Bayes, etc.) Bye!
Beta
Bye! And thanks for trying to help! :)
Cristy
+1  A: 

I suggest that you print out the RGB values of the first few pixel to make sure you're even grabbing the pixel data correctly. If your offsets are wrong, you'll never get this to work.

Derrick
Thanks for the ideea, I'll try that.
Cristy
A: 

Ok, finally I found a mistake that I think is the cause of this problem.

The pointer arithmetics:

        B= *(byteptr+pitch*j+3*i);
        G= *(byteptr+pitch*j+3*i+1);
        R= *(byteptr+pitch*j+3*i+2);

Are done for 24bits images, but the screenshot is a 32bits image that means I have to change the multiplier to 4 insteand of 3. That means:

    B= *(byteptr+pitch*j+4*i);
    G= *(byteptr+pitch*j+4*i+1);
    R= *(byteptr+pitch*j+4*i+2);

I think... I'll be back with an edit if this works or not.

EDIT: Yes it works, it gives the corect pixel position. Thanks everyone for your help :) .

Cristy