14

Can we find which color is dominant in an image with using java,imagemagick or jmagick?

Andrea
  • 11,073
  • 17
  • 60
  • 64
Erçin Akçay
  • 1,305
  • 3
  • 17
  • 34

6 Answers6

11

in java iterate on each pixel and determine color

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;


public class ImageTester {


    public static void main(String args[]) throws Exception {
        File file = new File("C:\\Users\\Andrew\\Desktop\\myImage.gif");
        ImageInputStream is = ImageIO.createImageInputStream(file);
        Iterator iter = ImageIO.getImageReaders(is);

        if (!iter.hasNext())
        {
            System.out.println("Cannot load the specified file "+ file);
            System.exit(1);
        }
        ImageReader imageReader = (ImageReader)iter.next();
        imageReader.setInput(is);

        BufferedImage image = imageReader.read(0);

        int height = image.getHeight();
        int width = image.getWidth();

        Map m = new HashMap();
        for(int i=0; i < width ; i++)
        {
            for(int j=0; j < height ; j++)
            {
                int rgb = image.getRGB(i, j);
                int[] rgbArr = getRGBArr(rgb);                
                // Filter out grays....                
                if (!isGray(rgbArr)) {                
                        Integer counter = (Integer) m.get(rgb);   
                        if (counter == null)
                            counter = 0;
                        counter++;                                
                        m.put(rgb, counter);                
                }                
            }
        }        
        String colourHex = getMostCommonColour(m);
        System.out.println(colourHex);
    }


    public static String getMostCommonColour(Map map) {
        List list = new LinkedList(map.entrySet());
        Collections.sort(list, new Comparator() {
              public int compare(Object o1, Object o2) {
                return ((Comparable) ((Map.Entry) (o1)).getValue())
                  .compareTo(((Map.Entry) (o2)).getValue());
              }
        });    
        Map.Entry me = (Map.Entry )list.get(list.size()-1);
        int[] rgb= getRGBArr((Integer)me.getKey());
        return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);        
    }    

    public static int[] getRGBArr(int pixel) {
        int alpha = (pixel >> 24) & 0xff;
        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;
        return new int[]{red,green,blue};

  }
    public static boolean isGray(int[] rgbArr) {
        int rgDiff = rgbArr[0] - rgbArr[1];
        int rbDiff = rgbArr[0] - rgbArr[2];
        // Filter out black, white and grays...... (tolerance within 10 pixels)
        int tolerance = 10;
        if (rgDiff > tolerance || rgDiff < -tolerance) 
            if (rbDiff > tolerance || rbDiff < -tolerance) { 
                return false;
            }                 
        return true;
    }
}
Zaz Gmy
  • 4,136
  • 2
  • 18
  • 29
8

I just released a very simple algorithm that can be translated in Java trivially. It is called color-finder and works in JavaScript.

The proposed solutions in this thread can be thrown off by a few white characters in the image, whereas mine really tries to find the most prominent color, even if all the pixels aren't really exactly of the same color.

Here is a live demo.

Let me know if you find that useful.

pieroxy
  • 892
  • 7
  • 13
  • Hi @pieroxy, this looks promising - yet the translation to Java doesn't feel that trivial to me - at least on first glimpse :-) – Jan May 06 '20 at 12:58
4

This is a tricky problem. For example, if you have a small area of exactly the same colour and a large area of slightly different shades of a different colour then simply looking for the colour that is used the most is unlikely to give you result you want. You would get a better result by defining a set of colours and, for each, the ranges of RGB values that you consider to 'be' that colour.

This topic is discussed at length on the ImageMagick discourse server, for example: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

See also Fast way of getting the dominant color of an image

Community
  • 1
  • 1
Martin Wilson
  • 3,336
  • 1
  • 22
  • 28
3

Using plain java you can just iterate over each pixel and count how often each color is contained...

pseudo-code:

Map<Color, Integer> color2counter;
for (x : width) {
   for (y : height) {
      color = image.getPixel(x, y)
      occurrences = color2counter.get(color)
      color2counter.put(color, occurrences + 1)
   }
}
Kai
  • 38,030
  • 14
  • 90
  • 102
1

assuming your using additive color scheme, where (0,0,0) is black and (255, 255, 255) is white (correct me if i'm mistaken). Also, if you just want to find the dominant color out of RGB:

One idea I have, which any of you are free to scrutinize is to have 3 variables that each store one of the RGB values and add to each of them the appropriate value of every pixel in the image and then divide by (255*numOfPixels) to get a ratio of color. Then compare the 3 ratios: .60 for red and .5 for green would mean red is more dominant.

This is just an idea, and might need tweaking...

DMor
  • 750
  • 2
  • 8
  • 17
  • i used jamagick for which color is used as RGB type but with this way i only can find avarage clor of image. But i have an idea i can crop image of middle so i can find avarage color of that part it will give nearly same color again. I find dominant color only :/ – Erçin Akçay May 10 '12 at 09:00
  • @ErçinAkçay If you want to crop the image, surely you want the main colour at the borders. e.g. say you have a large square surrounded by white. You want to detect the colour of the white to crop that, not the square. – Peter Lawrey May 10 '12 at 09:57
1

In other way, we can done this job with Color Thief library. More information can be found here and here.

Credit to @svenwoltmann and @lokeshdhakar.

Khai Nguyen
  • 3,021
  • 1
  • 30
  • 24