Search code examples
gimppython-fu

GIMP - Get a point within selection from python script


My script runs on a fuzzy selected area. I need to get the color value of the selected area from within python-fu script. This could be the average value of the selection area or, better, the color value of the pixel that user clicked on to make the fuzzy selection.

I can get the selection bounds and then somehow get a point within the selection to make use of pdb.gimp_image_pick_color. But I don't know how to get the point (which best represents the color of the selection) within any arbitrary shaped selection.

Could you please help?


Solution

  • A point inside the selection could be tricky, because you don't know if the selection is a single contiguous area.

    Two ways to do it:

    Using the histogram over the selection

    You can use pdb.gimp_drawable_histogram to get histogram values for each of the RGB channels in the selected pixels

    mean, std_dev, median, pixels, count, percentile=pdb.gimp_drawable_histogram(layer,HISTOGRAM_RED,0.,1.)
    

    Using the call three times (once for each channel) in this image selection:

    enter image description here

            | Average | Median |  Picker
    --------+---------+--------+---------     
      Red   |   44.0  |  44    |    47
    Green   |   54.2  |  54    |    56
     Blue   |   43.6  |  43    |    46
    

    The values obtained for the same area with the color picker in average mode aren't so far off.

    Using the color of a pixel

    • You can transform your selection in to a path with pdb.plug_in_sel2path(image, drawable). The result is a new path that is set active, so you can obtain it with path=image.active_vectors
    • You can check that you have a single stroke in path.strokes (otherwise you have a non-contiguous selection).
    • The list of all coordinates of the anchors in the single path stroke is:
    allX=path.strokes[0].points[0][2::6]
    allY=path.strokes[0].points[0][3::6]
    
    • If you average these two lists, you get the coordinates a pixel near the center (and hopefully, inside the selection if the selection is reasonably convex)
    • You can get the color of this pixel with pdb.gimp_drawable_get_pixel(), but this color may be quite different from the rest (in my test image above, the center pixel is (54, 62, 47), so somewhat lighter and redder than average).