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.)
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.)
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.
no module named numpy.core.multiarray; Segmentation fault
. Which part is dependent on this module?
Mar 9, 2018 at 22:15
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.
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.
Dec 8, 2010 at 11:08
xdtool getmouselocation
... very nice, thanks... sed's usefulness just keeps on amazing me!
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.
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
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.
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 !