Question

I need to get the color in hex code of the pixel beneath my mouse cursor. There are plenty fancy GUI-tools to solve this task, but I need a simple command line way to get the color, so that I can use the solution in a shell script.

Possibly I could use ImageMagick to take a (one pixel?) screenshot and extract the color from it (I can fetch the position using xdotool)). Maybe there is a simpler solution.

Any suggestions?

Was it helpful?

Solution

Not really satisfied with the other solution, I tried my ImageMagick idea. Works fine for me! (Depends on xclip, ImageMagick, xdotool, notify-send)

#!/bin/sh
# Get hex rgb color under mouse cursor, put it into clipboard and create a
# notification.

eval $(xdotool getmouselocation --shell)
IMAGE=`import -window root -depth 8 -crop 1x1+$X+$Y txt:-`
COLOR=`echo $IMAGE | grep -om1 '#\w\+'`
echo -n $COLOR | xclip -i -selection CLIPBOARD
notify-send "Color under mouse cursor: " $COLOR

EDIT:

Now using Gnome Shell, I have problems with the above solution (import won't take a screenshot of the visible windows, I don't know why. Hints are welcome). An alternative is to use a (fast) screenshot taker like scrot and use convert instead of import:

#!/bin/sh
# Get hex rgb color under mouse cursor, put it into clipboard and create a
# notification.

scrot --overwrite /tmp/copycolor.png
eval $(xdotool getmouselocation --shell)
IMAGE=`convert /tmp/copycolor.png -depth 8 -crop 1x1+$X+$Y txt:-`
COLOR=`echo $IMAGE | grep -om1 '#\w\+'`
echo -n $COLOR | xclip -i -selection CLIPBOARD
notify-send "Color under mouse cursor: " $COLOR

Update 2020: Newer versions of scrot require the "--overwrite" option to be set for this to work.

OTHER TIPS

Sure you can. But you need another linux package. If you're on Ubuntu just issue:

sudo apt-get install xdotool grabc

Then 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 will output the color.

But maybe it won't work from a script. For that purposes you might want to look at this topic on the Ubuntu forums.

Or if you don't mind, you can do it with python as described here.

Another method to get the pixel color, based on @Christian's excellent answer:

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

xwd is significantly faster than import on my system.

Fastest solution:

Edit/Update:

After reviewing new version of https://github.com/muquit/grabc I need to say that it beats anything else:

time ( COL=$(~/grabc/grabc -w $WINDOW_ID  -l +$X+$Y) ; echo COL=$COL )
COL=#2e2f30

real    0m0,006s
user    0m0,005s
sys     0m0,000s

Obviously this does not come with most of distros, so please use with caution. If you need something provided with your distro then old answer still stands:

time ( X=1 ; Y=1 ; xdotool mousemove --sync $X $Y sleep 0.01 click 1 \
       mousemove --sync restore & COL=$( grabc 2>/dev/null ) ; \
       echo COL=$COL )

COL=#ddedaa

real    0m0.046s
user    0m0.004s
sys     0m0.008s

There can be timing issues - i.e. sleep 0.01 part - but even increasing up to 0.1 it will be still faster than other solutions and you can detect error if $COL is empty.

If clicking is not an option, or timing issues are too problematic then I would probably go with import (then xwd then scrot if specific window shell makes problems)

Obviously for $X and $Y use eval $(xdotool getmouselocation --shell) or sth. similar

In comparison:

  • scrot

      time ( X=1 ; Y=1 ; scrot /tmp/copycolor.png ; \
             IMAGE=$(convert /tmp/copycolor.png -depth 8 -crop 1x1+$X+$Y txt:- ) ; \
             COL=$( echo $IMAGE | grep -om1 '#\w\+' ) ; \
             echo COL=$COL )
    
      COL=#DDEDAA
    
      real    0m0.590s
      user    0m0.596s
      sys     0m0.024s
    
  • xwd

      time ( X=1 ; Y=1 ; COL=$( xwd -root -silent | \
            convert xwd:- -depth 8 -crop "1x1+$X+$Y" txt:- | grep -om1 '#\w\+' ) ; \
            echo COL=$COL )
    
      COL=#DDEDAA
    
      real    0m0.387s
      user    0m0.380s
      sys     0m0.084s
    
  • import:

      time ( X=1 ; Y=1 ; IMAGE=$(import -window root -depth 8 -crop 1x1+$X+$Y txt:-) ;\
            COL=$( echo $IMAGE | grep -om1 '#\w\+' ) ; \
            echo COL=$COL )
    
      COL=#DDEDAA
    
      real    0m0.302s
      user    0m0.456s
      sys     0m0.044s
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top