12

Is there a command-line tool returns the colour value of a pixel, based solely on its screen co-ordinates.

Is there such a tool?

(Also: The tool should not require any user action. It is to run in a loop in a script.)

1

5 Answers 5

15

You can use the program grabc. It will turn your mouse pointer in a crosshair and return HTML and RGB values of the selected color.

sudo apt-get install grabc

Downside: it's not possible to do pixel-exact selections due to the crosshair not being thin enough.


You can also create a python script, something like:

#!/usr/bin/python -W ignore::DeprecationWarning
import sys
import gtk

def get_pixel_rgb(x, y):
    pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 1, 1)
    pixbuf.get_from_drawable(gtk.gdk.get_default_root_window(),
                             gtk.gdk.colormap_get_system(), 
                             x, y, 0, 0, 1, 1)
    return pixbuf.get_pixels_array()[0][0]

print get_pixel_rgb(int(sys.argv[1]), int(sys.argv[2]))

make it executable, and run pixel_rgb="$(/path/to/script.py x y)" in your bash script. Of course you'd need to alter the script the way you need it, add some error handling, and such.

PS: I'm not exactly sure you can do anything about the DeprecationWarning, so I turned it off in the first line.

4
  • Thanks htorque, but again I've realize too late that I've left out a significant requirement... I want it to run autonimously in a loop in a batch script. So thanks for the heads-up on this little app. It will definitely come in handy some time .. (but not for my current sutuation where is will be running "un-manned")
    – Peter.O
    Dec 8, 2010 at 10:15
  • htorque: Your Python script fits the bill perfectly for my ammended specs (typical user! always changing the specs! :) ... working directly on the co-ordinates is much better for my "find the pixel-pattern" proc... and then I can just xmacro the cursor to the just-found co-ords, and then xmacro a right click; right on target.... Easy! (for the Pythonistas :)
    – Peter.O
    Dec 8, 2010 at 11:40
  • Getting no module named numpy.core.multiarray; Segmentation fault. Which part is dependent on this module? Mar 9, 2018 at 22:15
  • grabc returns #030003 for everything I click on. This is not useful. Jun 8, 2023 at 7:40
7

This is a bit cludgy, but you can achieve this with xdotool which lets you interact with the mouse, and grabc which gets the colour from a location clicked on screen.

sudo apt-get install xdotool grabc

First run grabc but background it

grabc &

Then perform a mouseclick using xdotool

xdotool click 1

The click will be captured by grabc's cursor and the background process with output the color.

4
  • Interesting, misterben.. "cludgy" can be okay ;) I heard a saying recently. "black cat, white cat, tabby cat.. as long as it catches the mouse"... but I vaguely recall seeing something in one of the macro-tool's info page about pixels (but maybe it was only regarding co-ordinates)... I want to query a line of pixels across the screen, and I'd like to avoid the cursor switching caused by grabc... Now that I've seen "grabc" in action, I'd rather something which grabs the colour based on co-ordinates (I've done this quite often in Windows :( ... I hope there is something similar for Linux :)
    – Peter.O
    Dec 8, 2010 at 10:59
  • You could use xdotool to get the pointer coordinates and use them with htorque's python script. xdotool getmouselocation | sed -e 's/x://' -e 's/y://' -e 's/ screen:.*$//' will grab the coords and clean them down to space separated x y values to feed to that script.
    – misterben
    Dec 8, 2010 at 11:08
  • misterben, thanks for your help, I've learnt more about backgrouding (very handy).... I didn't realize it when I first asked the question, but the "get the colour by co-ordinates" method turned out to be the way to go.
    – Peter.O
    Dec 8, 2010 at 11:48
  • I just got around to trying your xdtool getmouselocation ... very nice, thanks... sed's usefulness just keeps on amazing me!
    – Peter.O
    Dec 8, 2010 at 12:12
4

A different solution, using xwd and xdotool:

xwd -root -silent | convert xwd:- -depth 8 -crop "1x1+$X+$Y" txt:- | grep -om1 '#\w\+'

where $X and $Y are your coordinates.

As part of Xorg xwd should come preinstalled on your system. xdotool can be installed with:

sudo apt-get install xdotool 

Based on @Christian's answer on a StackOverflow Q&A and this imagemagick.org thread.

2
  • Thanks, it does work, though it is much slower (real 0.363s user 0.456s sys 0.064s) than htorque's python script (real 0.097s user 0.072s sys 0.020s).
    – Peter.O
    Aug 27, 2014 at 16:05
  • @Peter.O Yes, but that's only true if python and the imported libraries are already cached in your memory. On a cold start the python script will be significantly slower. So if your script only runs occasionally you might want to use my solution. PS: You can speed things up if you know what window you want to inspect. xwd supports taking screenshots of specific window IDs, so you could query the window ID (e.g. xdotool search --name "$Win" | head -n1) and then pass it to xwd with xwd -id "$WinID" -silent | .... Note: coordinates would be relative to the window in this case. Aug 27, 2014 at 19:37
2

I have written a python module for operations like this, called Macropolo. But, it does much more things than simply getting the color of a pixel on the screen.

Here's the forum post where I've shared it: http://ubuntuforums.org/showthread.php?t=2155281

The module has many functions that allow you to e.g. count the amount of pixels that have a specific color in an area of the screen, search for pixel color(s) in area, wait for a pixel or an area of the screen have a specific color, wait for pixel color and run some other function while waiting (e.g. move the cursor for not letting the screen turn off while you are waiting for a specific color).

But, as I said, it does a lot more things, like simulating mouse clicks and keyboard, screenshot taking of area of the screen and more.

0

I wrote a little script using import and convert (from package imagemagick).

import allows you to take a screenshot, even a 1 px screenshot. convert allows you to transform it to text (what? a bad idea ? i don't know what you're talking about).

Here's the code :


#!/bin/bash

# import -window root -crop '{largeur}x{hauteur}+{position_x}+{position_y}' image.png
# convert image.png image.txt

if [[ -z $1 ]] || [[ -z $2 ]] || [[ $1 = "-h" ]] || [[ $1 = "--help" ]]; then
    echo "Returns the color of a pixel."
    echo "  Usage : $0 <x:int> <y:int> [<format:{1,2,3}>]"
    exit 1
fi

# Paths of temp files
path_png="/tmp/image_getpixelsh.png"
path_txt="/tmp/image_getpixelsh.txt"

# Parameters
position_x=$1
position_y=$2
format=$3

# Taking screenshot & converting it
import -window root -crop "1x1+$position_x+$position_y" $path_png
convert $path_png $path_txt

# Output depending on format
case $format in
    "1") tail -n 1 <$path_txt | cut -d "(" -f 2 | cut -d ")" -f 1 ;;
    "2") tail -n 1 <$path_txt | cut -d "#" -f 2 | cut -d " " -f 1 ;;
    "3") tail -n 1 <$path_txt | cut -d "#" -f 2 | cut -d " " -f 3 ;;
    *)
        tail -n 1 <$path_txt | cut -d "(" -f 2 | cut -d ")" -f 1
        tail -n 1 <$path_txt | cut -d "#" -f 2 | cut -d " " -f 1
        tail -n 1 <$path_txt | cut -d "#" -f 2 | cut -d " " -f 3
        ;;
esac

# Clean temp files
rm $path_png
rm $path_txt

Problem is : it's a bit slow, on my computer it takes like 9 secondes to run it 20 times, so it's about half a second to execute.

Whatmore, taking a bigger screenshot would make it harder to convert (a full screenshot converted to text produces a HUGE files, realy bad idea) and to process the convert's output. It would be nice to be able to pick various pixel from 1 screenshot, but easier to say than to do ^^'

I'll complete this answere if I take the time to make a better script ;-) Feel free to share any tips !

1
  • Welcome to AskUbuntu and thank you for contributing. Your answer seems to be straying slightly from the narrow question asked. Please only endeavor to specifically answer the question asked. If you have a insight/solution/script that you would like to share with the world and no question seems to ask explicitly for it, you are welcome to ask a new question to set up a page for it, then post your script as an educational answer to your own question -- this is part of the evolved/strict Stack Exchange Q&A design. Please take the tour. Feb 5, 2022 at 6:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .