site  contact  subhomenews

Get the colour of any screen pixel

October 13, 2021 — BarryK

I am currently investigating how to manage the situation when bootup results in a black screen. As has been the case with my "new" Nvidia GT218 video card, as reported yesterday:

https://bkhome.org/news/202110/the-mysterious-nomodeset-kernel-option.html

I now do have a working desktop on that PC, but have been thinking about mechanisms for anyone else who might encounter the same situation. It occurred that it would be nice if EasyOS could automatically detect when the blank screen occurs...

There is a way. After Xorg server has started, read a pixel off the screen. If it's colour is black, then we have a blank screen ...probably. Well, will have to experiment with the proposed utility, but anyway, thought this could be a useful little utility to have.

Hunted around, found some code that uses GTK and GDK to read the mouse pointer position and display pixel colour. But wanted something simpler, just using X11, found some code here:

https://stackoverflow.com/questions/17518610/how-to-get-a-screen-pixels-color-in-x11

...that code needed a bit of fleshing-out, did so, and created 'getpixelcolor.c'. Easy to use, just feed in x/y coordinates. Let's see, get coordinates over the top-left icon:

# ./getpixelcolor 40 40
#F6F5F4

Returns 0 and prints the colour, in "#rrggbb" format, if no display returns 1, if unable to get the pixel returns 2. If no x/y on commandline, defaults to 10/10. It will be in /usr/sbin in next release of EasyOS.

The package 'pup-tools' already has a similar X11 utility 'getcurpos', have added 'getpixelcolor' to the package. Source package (41KB):

http://distro.ibiblio.org/easyos/source/alphabetical/p/pup-tools-20211013.tar.gz

This has been compiled in OpenEmbedded, for x86_64 and aarch64. x86_64 package is here (100KB):

http://distro.ibiblio.org/easyos/amd64/packages/compat/oe/dunfell/pup-tools-20211013-r4-nocona-64.tar.xz

Now have to play with the utility on my old HP workhorse.

EDIT:
Ha ha, no, my faulty reasoning! The black screen is the monitor, but the video memory in the Nvidia card is returning colours. So, it is useful to test if not getting anything in the card memory, but in my case the problem is not getting anything on the monitor. Needs more thought!
 

EDIT 2021-10-14:
Here is the code for 'getpixelcolor.c':

/* Barry Kauler 2021 bkhome.org License: GPLv2
* based upon code found here:
* https://stackoverflow.com/questions/17518610/how-to-get-a-screen-pixels-color-in-x11
* optional, "x y" coordinates on commandline, will return pixel colour.
* without commandline coords, will return colour at 10,10 coords.
* how to compile:
* cc -o getpixelcolor getpixelcolor.c `pkg-config --libs --cflags x11`
* um, this is enough:
* cc -o getpixelcolor getpixelcolor.c -lX11
*/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
XColor c;
Display *d = XOpenDisplay((char *) NULL);
if (d == NULL) { return 1; }

int x=10; // Pixel x
int y=10; // Pixel y

if (argc==3) {
x=atoi(argv[1]);
y=atoi(argv[2]);
}

XImage *image;
image = XGetImage (d, XRootWindow (d, XDefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
if (image == NULL) {
XCloseDisplay(d);
return 2;
}

c.pixel = XGetPixel (image, 0, 0);
XFree (image);
XQueryColor (d, XDefaultColormap(d, XDefaultScreen (d)), &c);

XCloseDisplay(d);

//print colour of pixel in format #rrggbb
printf("#%06X\n", c.pixel);
fflush(stdout);

return 0;
}

 ...pretty simple. The stripped executable is 14KB.  

Tags: easy