如何找到图像的主色?

我们可以使用java,imagemagick或jmagick找到图像中哪种颜色占主导地位?

在java中迭代每个像素并确定颜色

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; } } 

我刚刚发布了一个非常简单的算法,可以用Java轻松翻译。 它被称为颜色查找器 ,适用于JavaScript。

此线程中提出的解决方案可能会被图像中的一些白色字符抛弃,而我的确会尝试找到最突出的颜色,即使所有像素并非真正完全相同的颜色。

这是一个现场演示 。

如果您觉得有用,请告诉我。

这是一个棘手的问题。 例如,如果你有一个完全相同颜色的小区域和一个不同颜色的略有不同色调的大区域,那么只是寻找最常用的颜色不太可能给你想要的结果。 您可以通过定义一组颜色获得更好的结果,并且对于每个颜色,您可以考虑“成为”该颜色的RGB值范围。

在ImageMagick话语服务器上详细讨论了该主题,例如: http : //www.imagemagick.org/discourse-server/viewtopic.php? f = 1&t = 12878

另请参见获取图像主色的快速方法

使用普通java,您可以迭代每个像素并计算每种颜色的包含频率……

伪代码:

 Map color2counter; for (x : width) { for (y : height) { color = image.getPixel(x, y) occurrences = color2counter.get(color) color2counter.put(color, occurrences + 1) } } 

换句话说,我们可以使用Color Thief库完成这项工作。 可在此处和此处找到更多信息。

感谢@svenwoltmann和@lokeshdhakar。

假设您使用加性颜色方案,其中(0,0,0)是黑色,(255,255,255)是白色(如果我弄错了,请纠正我)。 此外,如果您只想找到RGB的主色:

我有一个想法,你们任何人都可以自由审查是有3个变量,每个变量存储一个RGB值,并为每个变量添加图像中每个像素的适当值,然后除以(255 * numOfPixels)获得颜色比例。 然后比较3个比率:.60表示红色,0.5表示绿色表示红色表示更优势。

这只是一个想法,可能需要调整……