nonchip
nonchip

Reputation: 1139

how to get a screen pixel's color in x11

I want to get the RGB value of the top/left pixel (0;0) of the whole x11 display.

what I've got so far:

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

XImage *image;
image = XGetImage (d, RootWindow (d, DefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
c->pixel = XGetPixel (image, 0, 0);
XFree (image);
XQueryColor (d, DefaultColormap(d, DefaultScreen (d)), c);
cout << c.red << " " << c.green << " " << c.blue << "\n";

but I need those values to be 0..255 or (0.00)..(1.00), while they look like 0..57825, which is no format I recognize.

also, copying the whole screen just to get one pixel is very slow. as this will be used in a speed-critical environment, I'd appreciate if someone knows a more performant way to do this. Maybe using XGetSubImage of a 1x1 size, but I'm very bad at x11 development and don't know how to implement that.

what shall I do?

Upvotes: 8

Views: 9999

Answers (2)

parkydr
parkydr

Reputation: 7802

I took your code and got it to compile. The values printed (scaled to 0-255) give me the same values as I set to the desktop background image.

#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

using namespace std;

int main(int, char**)
{
    XColor c;
    Display *d = XOpenDisplay((char *) NULL);

    int x=0;  // Pixel x 
    int y=0;  // Pixel y

    XImage *image;
    image = XGetImage (d, XRootWindow (d, XDefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
    c.pixel = XGetPixel (image, 0, 0);
    XFree (image);
    XQueryColor (d, XDefaultColormap(d, XDefaultScreen (d)), &c);
    cout << c.red/256 << " " << c.green/256 << " " << c.blue/256 << "\n";

    return 0;
}

Upvotes: 13

Jim Garrison
Jim Garrison

Reputation: 86774

From the XColor(3) man page:

The red, green, and blue values are always in the range 0 to 65535 inclusive, independent of the number of bits actually used in the display hardware. The server scales these values down to the range used by the hardware. Black is represented by (0,0,0), and white is represented by (65535,65535,65535). In some functions, the flags member controls which of the red, green, and blue members is used and can be the inclusive OR of zero or more of DoRed, DoGreen, and DoBlue.

So you must scale these values to whatever range you want.

Upvotes: 2

Related Questions