java 如何找到图像的主色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10530426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can i find dominant color of an image?
提问by Er?in Ak?ay
Can we find which color is dominant in an image with using java,imagemagick or jmagick?
我们可以使用 java、imagemagick 或 jmagick 找到图像中哪种颜色占主导地位?
采纳答案by Zaz Gmy
in java iterate on each pixel and determine color
在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;
}
}
回答by pieroxy
I just released a very simple algorithm that can be translated in Java trivially. It is called color-finderand works in JavaScript.
我刚刚发布了一个非常简单的算法,可以简单地用 Java 翻译。它被称为颜色查找器,在 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.
该线程中提出的解决方案可能会被图像中的几个白色字符所抛弃,而我的确实试图找到最突出的颜色,即使所有像素的颜色并不完全相同。
Let me know if you find that useful.
如果您觉得这有用,请告诉我。
回答by Martin Wilson
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.
这是一个棘手的问题。例如,如果您有一小块颜色完全相同的区域和一大块颜色略有不同的不同颜色的区域,那么仅仅寻找最常用的颜色不太可能给您想要的结果。通过定义一组颜色以及您认为“是”该颜色的 RGB 值范围,您将获得更好的结果。
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
这个话题在 ImageMagick 话语服务器上有详细的讨论,例如:http: //www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878
See also Fast way of getting the dominant color of an image
另请参阅获取图像主色的快速方法
回答by Kai
Using plain java you can just iterate over each pixel and count how often each color is contained...
使用普通的Java,您可以遍历每个像素并计算包含每种颜色的频率...
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)
}
}
回答by DMor
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:
假设您使用加色方案,其中 (0,0,0) 是黑色,(255, 255, 255) 是白色(如果我弄错了,请纠正我)。另外,如果您只想从 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.
我有一个想法,你们中的任何一个人都可以自由地仔细检查是有 3 个变量,每个变量存储一个 RGB 值,并将图像中每个像素的适当值添加到每个变量中,然后除以 (255*numOfPixels)以获得颜色的比例。然后比较 3 个比率:红色为 0.60,绿色为 0.5 意味着红色更占优势。
This is just an idea, and might need tweaking...
这只是一个想法,可能需要调整......