Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I grab the color of a pixel on my desktop? (Linux)

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 :)

like image 525
Joernsn Avatar asked Oct 22 '09 06:10

Joernsn


4 Answers

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.

like image 147
richq Avatar answered Nov 16 '22 09:11

richq


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]))))
like image 28
Harvey Avatar answered Nov 16 '22 10:11

Harvey


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...

like image 41
Oleh Prypin Avatar answered Nov 16 '22 10:11

Oleh Prypin


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

like image 34
aberpaul Avatar answered Nov 16 '22 09:11

aberpaul