Color sampling in pictures

edited April 2015 in How To...

Hey, I've been wondering if it was possible to sample color from a picture and get quantitative results from it. For example, if i took a screenshot from this forum and passed it in the script it would then tell me each color with the amount of pixels that are the same color:

"(11,32,52) 4987 pixels (255, 255, 255) 2312 pixels (0,0,0) 625 pixels"

and so on for every color in my screenshot. It actually is a major part of what will become (in the next three weeks) a graphic design project about our relationship with digital content. Since i'm brand new to processing, if anyone could give me a hand, i would truly appreciate it!

Thanks! (and if anyone is interested with helping me to build a code to generate the whole printed book i'd love to collaborate!)

Answers

  • It is possible that you will have many, many colors that are just slight variations of one another. Especially if what you are taking screenshots of has shadows or gradients

    This could cause a problem if you want to determine whether or not you have already seen a color before when iterating over all pixels. Basically the problem is that using simple data structures like an array or ArrayList will require too much computation time to do what you want (or at least in a reasonable amount of time)

    I did a quick Google search for Processing Maps and found HashMap code. I am accustomed to Maps in C++ but it seems to be what is needed for quickly determining if a color has already been seen. Have to warn you that I am not accustomed to the HashMap I used below, I just followed documentation at these links:


    The code below does not use screenshots, I just made up a scene in Processing and then counted the colors of that scene. The code just shows how to use the HashMap and iterate over all pixels:

    import java.util.Map;
    
    void setup() {
      size(200, 200, P2D);
      noStroke();
    
      background(255);
    
      // 10,000 red
      fill(255, 0, 0);
      rect(0, 0, 100, 100);
    
      // 10,000 green
      fill(0, 255, 0);
      rect(100, 100, 100, 100);
    
      // There will be 20,000 white due to background
    
    
      // Use a HashMap for storing the colors
      // There will probably be many, many colors for a screenshot later
      // The HashMap will allow you to quickly determine if you have a repeat color
      HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
    
      loadPixels();
    
      // Loop over all of the pixels
      for (int i = 0; i < width*height; i++) {
        // If the HashMap does not contain some color
        if (!hm.containsKey(pixels[i]))
          // Then add that color to the HashMap with a count of 1
          hm.put(pixels[i], 1);
    
        // If the HashMap does contain some color  
        else
          // Then increase the count of that color
          hm.put(pixels[i], hm.get(pixels[i])+1);
      }
    
    
      // Results:
      // -16711936 (red) has a count of 10,000
      // -1 (white) has a count of 20,000
      // -65,536 (green) has a count of 10,000
      for (Map.Entry i : hm.entrySet ())
        println(i.getKey() + " is " + i.getValue());
    }
    
  • edited April 2015

    Oh I was l8! Anyways, here's my lil' util function: :-\"

    // forum.processing.org/two/discussion/10405/color-sampling-in-pictures
    
    import java.util.Map;
    
    static final Map<Integer, Integer> getColorCount(PImage img) {
      Map<Integer, Integer> m = new HashMap<Integer, Integer>();
      Integer v;
      img.loadPixels();
    
      for (Integer c : img.pixels)  m.put(c, (v = m.get(c)) == null? 1 : v + 1);
    
      return m;
    }
    
Sign In or Register to comment.