Getting pixel colors

Looking for an easy(ish) way to get pixel colors without windows.h

I know you can do it using X but I found that quite damn confusing, any explanation of X's method of doing it is appreciated. :D
Last edited on
Linux :D
Well there you go.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;
#include <fstream>

#include <X11/Xlib.h>

void GetPix(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);
}

int main()
{
    XColor c;
    ofstream file;
    file.open("log.txt");
    register int x;
    register int y;
    for (register int x = 0; x < 1024; x++ )
    {


        for(register int y = 0; y < 768; y++)
        {
            GetPix(Display, x, y, &c );
            file << c.red << "  " << c.green << "  " << c.blue;
            file << endl;

        }

    }
    cout << "Done";
    return 0;

}


That's my code so far the GetPix(); is taken from rosettacode, but I have 2 compile errors:

XGetPixel was not defined in this scope.
And the typical 'expected primary expression before ; token' (line 29)
Last edited on
Included Xutil.h and I'm down to "expected primary-expression before ; token" still
Last edited on
So what exactly is the variable Display on that line?
Display is a variable type not a variable, I'm having trouble actually creating a variable of type Display
Well just saying the name of the variable type isn't going to do it :)

Display *d = XOpenDisplay((char *) NULL);
Display *d = XOpenDisplay((char *) NULL); works, but now I have a bunch of 'undefined references' for:

XGetImage
XFree
XOpenDisplay
XQueryColor

Code atm:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;
#include <fstream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>

Display *d = XOpenDisplay((char *) NULL);

void GetPix(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);
}

int main()
{
    XColor c;
    ofstream file;
    file.open("log.txt");
    register int x;
    register int y;
    for (register int x = 0; x < 1024; x++ )
    {

        for (register int y = 0; y < 768; y++)
        {
            GetPix(d, x, y, &c );
            file << c.red << "  " << c.green << "  " << c.blue;
            file << endl;

        }

    }
    cout << "Done";
    return 0;

}
Undefined reference is a linker error. That indicates that your code was compiled fine. Such a linker error generally indicates that you are not linking to the correct libraries. I link to it with the switch

-lX11

in my compile command.
-lX11

Works!

+1 Brilliant teacher :D

Any ideas on how to make it run a bit faster? It's extremely slow
You appear to be running 1024*768 individual screendumps. Perhaps you could only do that once, and just read all the pixels from that one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
using namespace std;
#include <fstream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>

Display *d = XOpenDisplay((char *) NULL);
XImage *image;
void something(Display *d, int x, int y)
{
    image = XGetImage (d, RootWindow (d, DefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
}

void GetPix(Display *d, int x, int y, XColor *color)
{
  color->pixel = XGetPixel(image, x, y);
  XQueryColor (d, DefaultColormap(d, DefaultScreen (d)), color);
}

int main()
{
    something(d, 0, 0);
    XColor c;
    ofstream file;
    file.open("log.txt");
    register int x;
    register int y;
    for (register int x = 0; x < 1024; x++ )
    {

        for (register int y = 0; y < 768; y++)
        {
            GetPix(d, x, y, &c );
            file << c.red << "  " << c.green << "  " << c.blue;
            file << endl;

        }

    }
    XFree (image);
    cout << "Done";
    return 0;

}


Like so?
It's your code; you tell us. :) Faster?
Faster, but I've never worked with X before so I'd be oblivious if my code was doing the totally wrong thing. c.red c.green c.blue seem to be 16-bit ints rather than 8-bit 0.0
Dig deeper into the image to check such things: http://tronche.com/gui/x/xlib/graphics/images.html#XImage
*Tear* Java's robot class is so much easier *Sniff* :(
Topic archived. No new replies allowed.