Reputation: 47
I want to type a 6-digit-number (RGB-hex) and then click on a button to show the color's name. I did not find color lib in java to give me arbitrary colors' names.
So what I do is : I found this lib in javascript this is the ntc js lib and tried to re-implement it in java , so I defined a hash map and put each value with the name for example :
sColorNameMap.put("B43332", "Well Read");
The code runs ok when given the same key which I put in the hash map, for example when I write the value B43332 then I get Well Read as name of color.
My problem: When I enter a value not equal to the key I pushed then I can not get the name of color.
What I need : I need a function to return the name of the closest matching color. I tried to understand how ntc does it but I couldn't.
For example the value B23634
is not pre-defined in ntc js lib BUT it resolves to give the name Well Read , like this picture :
So any help to implement a function returning the closest value (6 digit of number) to a certain color is appreciated.
Upvotes: 0
Views: 124
Reputation: 2828
If you consider the closest matching color as the one closest in the 3 dimensional RGB space, you can use something like this:
(check this for information on how to calculate that distance)
public static void main(String[] args) {
Map<String, String> sColorNameMap = new HashMap<>();
String rgbCode = "B23634";
String colorName;
if (sColorNameMap.containsKey(rgbCode)) {
colorName = sColorNameMap.get(rgbCode);
} else {
colorName = nearestColor(rgbCode, sColorNameMap);
}
System.out.println("colorName = " + colorName);
}
private static String nearestColor(String code, Map<String, String> sColorNameMap) {
int[] rgb = getRgb(code);
double nearestDistance = Double.MAX_VALUE;
String nearestNamedColorCode = null;
for (String namedColorCode : sColorNameMap.keySet()) {
int[] namedColorRgb = getRgb(namedColorCode);
double distance = calculateDistance(rgb, namedColorRgb);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestNamedColorCode = namedColorCode;
}
}
return sColorNameMap.get(nearestNamedColorCode);
}
private static int[] getRgb(String code) {
int r = Integer.parseInt(code.substring(0, 2), 16);
int g = Integer.parseInt(code.substring(2, 4), 16);
int b = Integer.parseInt(code.substring(4, 6), 16);
return new int[]{r, g, b};
}
private static double calculateDistance(int[] rgb1, int[] rgb2) {
double sum = 0.0;
for (int i = 0; i < 3; i++) {
sum += Math.pow(rgb2[i] - rgb1[i], 2);
}
return Math.sqrt(sum);
}
If you have some other metric for closest matching color, it is just the matter of changing the implementation in calculateDistance()
method.
Upvotes: 1