Question

I want to grab the color of a pixel with known coordinates on my Linux desktop.

Until now, I've used "import -window SomeWindow -crop 1x1+X+Y /tmp/grab.jpg" then extracting the pixel value using Python and PIL.

This does the job, but since import grabs the whole window before cropping, it's very slow :(

Are there any clever way to grab the color of only one pixel? I know both relative (window) and absolute coordinates.

A Python or shell script would be preferable, but if you know some clever C/X11 functions, also please let me know :)

Was it helpful?

Solution

This does the trick, but requires python-gtk:

import gtk.gdk
import sys

def PixelAt(x, y):
    w = gtk.gdk.get_default_root_window()
    sz = w.get_size()
    pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1])
    pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1])
    pixel_array = pb.get_pixels_array()
    return pixel_array[y][x]

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

On Ubuntu 9.10, this also requires python-numpy or it segfaults the python interpreter on the get_pixels_array line. Ubuntu 10.04 it still has this requirement, or it causes an ImportError regarding numpy.core.multiarray.

OTHER TIPS

Here is a much faster function based on richq's answer.
This one reads only one pixel from the screen instead of getting a huge array of all the pixels.

import gtk.gdk

def pixel_at(x, y):
    rw = gtk.gdk.get_default_root_window()
    pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 1, 1)
    pixbuf = pixbuf.get_from_drawable(rw, rw.get_colormap(), x, y, 0, 0, 1, 1)
    return tuple(pixbuf.pixel_array[0, 0])
>>> pixel_at(25, 5)
(143, 178, 237)

Requires PyGTK, of course...

Using gi.repository Gdk, it's even smaller and works on either Python 2 or 3:

#!/usr/bin/python3
# Print RGB color values of screen pixel at location x, y
from gi.repository import Gdk
import sys

def PixelAt(x, y):
  w = Gdk.get_default_root_window()
  pb = Gdk.pixbuf_get_from_window(w, x, y, 1, 1)
  return pb.get_pixels()

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

If you are using KDE4 there is a Color Picker Widget that you can add to either your panel or your Desktop. To add the widget either right click on the Desktop and choose add widget OR right click on the panel and choose Panel Options > Add Widgets

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top