black swan
black swan

Reputation: 47

How to make rang for color in java?

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 : here I enter number not predifined and the number close to the closet color name 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

Answers (1)

Ward
Ward

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

Related Questions