将Color对象“舍入”到最接近的颜色常量的最佳方法是什么?

我将检索像素的确切颜色,并希望将该确切颜色与Color.blue类的常量相关联。 有没有一种简单的方法可以“舍入”到最近的颜色常数? 另外,有没有办法定义自己的颜色常数?

基本方法是通过简单地将样本与每个样本进行比较,找到最接近样本的标准颜色。 当然,问题在于定义“最接近的”。 最明显的是在RGB空间中使用欧几里德距离。 问题是这个距离与我们对“最接近的颜色”的感知感很不一致。 在本文中可以找到对此问题的讨论,以及一个很好的(易于计算的)度量(包括伪代码!)。

编辑:以防万一该文章的链接死了(或者如果你很懒,并且愿意使用代码而不了解它的作用),这里是我的Java版本的“颜色距离函数”,本文建议“低” – 成本近似“到他们推荐的距离函数(RGB空间中的加权欧氏距离):

 double colorDistance(Color c1, Color c2) { int red1 = c1.getRed(); int red2 = c2.getRed(); int rmean = (red1 + red2) >> 1; int r = red1 - red2; int g = c1.getGreen() - c2.getGreen(); int b = c1.getBlue() - c2.getBlue(); return Math.sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)); } 

请注意,如果您只是要对颜色距离进行排名,则可以省去对Math.sqrt()的调用,从而节省一些计算成本。

可能最好的方法是循环遍历每个常量,并比较各自的RGB通道( getRedgetGreengetBlue )。 跟踪最接近的那个。

 Color color = new Color(...); Color[] constantColors = new Color[] { Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink, Color.red, Color.white, Color.yellow }; Color nearestColor = null; Integer nearestDistance = new Integer(Integer.MAX_VALUE); for (Color constantColor : constantColors) { if (nearestDistance > Math.sqrt( Math.pwr(color.getRed() - constantColor.getRed(), 2) - Math.pwr(color.getGreen() - constantColor.getGreen(), 2) - Math.pwr(color.getBlue() - constantColor.getBlue(), 2) ) ) { nearestColor = color; } } 

不,您不能在类中添加颜色常量,但您可以创建自己的类来保存常量。

 class MyColors { public static final Color heliotrope = new Color(...); } 

编辑:添加差异算法,感谢@Ted的链接。

您可以将Java的内置颜色转换与包含可能颜色调色板的IndexColorModel一起使用。 在内部,该类使用颜色分量上的欧几里德距离来确定最接近的颜色。

 import java.awt.Color; import java.awt.image.DataBuffer; import java.awt.image.IndexColorModel; public class ColorConverter { private final Color[] colors; private final IndexColorModel colorModel; public ColorConverter(Color[] colors) { this.colors = colors; this.colorModel = createColorModel(colors); } private static IndexColorModel createColorModel(Color[] colors) { final int[] cmap = new int[colors.length]; for (int i = 0; i