The method always return the last Color of the palette because the variable minDistance is not updated and the Color distance shoul be in absolute value. Regards The resolution is public HSSFColor findSimilarColor(byte red, byte green, byte blue) { HSSFColor result = null; int minColorDistance = Integer.MAX_VALUE; byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX); for (short i = (short) PaletteRecord.FIRST_COLOR_INDEX; b != null; b = palette.getColor(++i)) { int colorDistance = Math.abs(red - b[0] + green - b[1] + blue - b[2]); if (colorDistance < minColorDistance) { minColorDistance = colorDistance; result = getColor(i); } } return result; }
That resolution wouldn't work properly, as long as distance isn't being calculated properly: If the desired color is 254,0,0: - The color 0,254,0 will have colorDistance==0, but colors are really different. - The color 255,0,0, although is really similar (colorDistance==1), won't be chosen because there is another color (the previous one) with less colorDistance. In my opinion, a better way for calculating the colorDistance would be: int colorDistance = Math.abs(r - comp[0]) + Math.abs(g - comp[1]) + Math.abs(b - comp[2]) Once the colorDistance is calculated properly, a breaking condition can be added before the comparision (colorDistance < minColorDistance) when the exact color is found: if (colorDistance==0) { return getColor(i); }
I agree with Néstor.
I've applied Néstor's suggested fix to svn trunk. I've also written some tests, which show that it is now working as one would expect it to.
*** Bug 44664 has been marked as a duplicate of this bug. ***