Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Wizard advice requested: Struggling to write plug in that lists color data
TL,DR:  Looking to quickly and automatically generate a list of each unique color in an image with pixel counts.

Hi everyone - 
I have been struggling to write this plugin for too long and don't typically ask for help, but despite my best attempts at reverse-engineering, I just can't seem to get my head wrapped around this one and am about to give up.  I thought I would try here as a desperate final plea.

I am making art from pixelated images, so I take RGB images and convert them to Indexed color 8-bit images using a specific custom palette of 120 colors representing the available manufacturer colors.  My custom palette has the RGB and manufacturer color codes in the palette (i.e. color "black" is C02).  I am trying to create a quick easy way to see how much of each color I will need before starting the art project so I can buy / have enough material on-hand.

Right now, this is how I have to accomplish it...  After converting the RGB image to the custom palette, I view the colormap and see each of the individual colors used.  By selecting-by-color for each item in the colormap, I can see the pixel count on the Histogram.  Then using the HTML Notation (HEX code) from the colormap, I find the corresponding color on my spreadsheet and then enter in the total pixel count for this project.  Then I do that for the next color until I've hit 120 or however many are in the image.  This is seriously time consuming.

Since all this data is so easily available in Gimp, I feel like it has to be possible to have a plugin do all this, and at this point I would be SO happy with any system that reduces the time it takes me.  I'm not a newbie to programming, but I'm not familiar with Python and I've attempted to create scripts in Python and Script-Fu to accomplish it, but there's a shocking lack of information about this online and so far I haven't been able to figure it out.  I'm to the point where I think some of this data is only accessible in C: and that's just not happening.

So for my final goal, the absolute best-case scenario is one where the plugin creates a .txt or .csv file that references the custom palette and lists each manufacturer code with the number of pixels.  Second-best is an exported file (or even a list in the Error Console) with the HEX code (or RGB codes) of each individual color with its pixel count.

Thanks in advance for any help!

Edit:  Honestly it seems like this information should be available via Colors->Info->Export Histogram... but for whatever reason the amount of info you can get from that export is seriously lacking.  I would be happy just to have that function work properly lol.  On another note completely, in the future, it would be great to have intelligent custom palettes in Gimp, so I could select-by-color from my palette, etc.

Edit #2:  Okay I discovered a very interesting piece of information... the colormap tab indexes the colors in descending order of proportion in the image.  That means the colormap must inherently know how many pixels of each color exist in the image, even though it doesn't display that info. 
Here's how I'd do it:
from gimpfu import *
import pygtk
import gtk
#import sys
#sys.stderr = open('C:/temp/python-fu-output.txt','a')
#sys.stdout=sys.stderr # So that they both go to the same file

def kmullinax(image,drawable):
  palette_name = pdb.gimp_context_get_palette()   # get the name of the currently selected palette
  num_colours, colours = pdb.gimp_palette_get_colors(palette_name)  # get the list of colours to search
  Report = 'Using Palette: "%s" with %d colours\n' % (palette_name, num_colours)
  TotalCount = 0
  pdb.gimp_context_set_sample_threshold(0.0)    # only select exact colours
  for this_colour in colours: # for each colour in the palette
    colour_name = pdb.gimp_palette_entry_get_name(palette_name, colour_num) # find out what this colour's name is
    pdb.gimp_image_select_color(image, 2, drawable, this_colour)  # select this colour
    if pdb.gimp_selection_is_empty(image) :  # If there isn't any of this colour present, the histogram count returns all of the pixels in the image
      count = 0
      mead, std_dev, median, pixels, count, percentile = pdb.gimp_drawable_histogram(drawable, 0, 0.0, 1.0) # get the number of pixels of this colour
    TotalCount += count
    Report += "%s, %d\n" % (colour_name, count)
    colour_num += 1
  Report += "Total count=%d\n" % (TotalCount)
# menu registration
    "Get pixel counts for a Palette",  # Tooltip
    "Get pixel counts for a Palette",
    "Get pixel counts for a Palette",  # Menu label
      (PF_IMAGE,      "image",       "Input image", None),
      (PF_DRAWABLE,   "drawable", "Input drawable", None),


Which makes this output on the error console:
Okay, first of all.... THANK YOU!!!!
Thank you so much for the response, and after reading through it, I'm embarrassed that I needed the help.
I totally understand what you're doing here and I guess I just needed to see it.
You have just saved me a TON of time in the future.

There was a problem with it where not all of the colors were being selected... the name of the color would appear in the list but the pixel count would be reported as 0 when it should have had a large number.  Which meant the total pixel count ended up being significantly less than the actual count.

I tried to solve it myself by changing various inputs with the histogram command, which didn't solve it.
Then I played around with changing the pdb.gimp_context_set_sample_criterion to 6 which did something but just skewed the results in the other direction.
Finally I changed the pdb.gimp_context_set_sample_threshold to 0.01 from 0.0 and that worked.  I checked the results against ones I did the manual way and everything was perfect, and the total count was correct.

Anyway, thanks so much again!   Smile

Forum Jump: