3

I have a question regarding the awt Color class in Java.

I am currently using the class abbreviations such as Color.RED and Color.BLACK. I also have a list of three integers such as the following:

int var1 = 0
int var2 = 0
int var3 = 255

Is there a method to convert these integers into the appropriate Java Color name?

Neuron
  • 5,141
  • 5
  • 38
  • 59
  • 1
    Are you looking to create a colour using those 3 variables (because there's a Color constructor that does that), or getting the associated abbreviation (in your example, `Color.BLUE`)? – AntonH Apr 28 '14 at 16:21
  • 3
    Colors don't have names. – JB Nizet Apr 28 '14 at 16:22
  • 4
    Maybe a duplicate to this : http://stackoverflow.com/questions/4126029/java-color-code-convert-to-color-name – javadev Apr 28 '14 at 16:22
  • [Check Documentation](http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html) As AntonH said, if you just want to create a new Color you can do `Color(float r, float g, float b)` – DoubleDouble Apr 28 '14 at 16:26
  • Or, since you're indicating `int`s, `Color (int r, int g, int b);`. – AntonH Apr 28 '14 at 16:27
  • your question does not make sense at all and I agree with JB Nizet, "colors do not have names" Can you change your question? – Kick Buttowski Apr 28 '14 at 16:28
  • http://stackoverflow.com/questions/18022364/how-to-convert-rgb-color-to-int-in-java. take a look at this – Kick Buttowski Apr 28 '14 at 16:30
  • Apologies for the poor wording, when I use the method Color(0, 0, 255) I get the error cannot find symbol pointing to method Color(int,int,int), despite the fact I have imported java.awt.Color? –  Apr 28 '14 at 16:54
  • @user3371750 Cannot find which symbol? – The Guy with The Hat Apr 28 '14 at 16:55
  • You need to use the `new` operator to create a new instance of Color: `new Color(0, 0, 255)` – Erwin Bolwidt Apr 28 '14 at 17:00

4 Answers4

4

There is no way to do this with a single method in the Java core classes. However, you can fairly easily do this yourself in two ways.

First way

First, create a HashMap of Colors that contains all the colors you want:

HashMap<Color, String> colors = new HashMap<Color, String>();

colors.put(Color.BLACK,            "BLACK");
colors.put(Color.BLUE,             "BLUE");
colors.put(Color.CYAN,             "CYAN");
colors.put(Color.DARK_GRAY,        "DARK_GRAY");
colors.put(Color.GRAY,             "GRAY");
colors.put(Color.GREEN,            "GREEN");
colors.put(Color.LIGHT_GRAY,       "LIGHT_GRAY");
colors.put(Color.MAGENTA,          "MAGENTA");
colors.put(Color.ORANGE,           "ORANGE");
colors.put(Color.PINK,             "PINK");
colors.put(Color.RED,              "RED");
colors.put(Color.WHITE,            "WHITE");
colors.put(new Color(192, 0, 255), "PURPLE");
colors.put(new Color(0xBADA55),    "BADASS_GREEN");
colors.put(new Color(0, 0, 128),   "DARK_BLUE");

Then, create a new Color out of the RGB values you have:

Color color = new Color(var1, var2, var3);

Last, get the value in colors for the key color:

String colorName = colors.get(color);

Second way

This is potentially a less brittle way, but does have issues, and doesn't work as-is. You'll need to catch some exceptions, and maybe handle the case where a field isn't static and you can't just do f.get(null).

Create a new Color out of the RGB values you have:

Color color = new Color(var1, var2, var3);

Then

  1. Get the Class object from the Color class with getClass().
  2. Get the fields from that with getDeclaredFields().
  3. Stream it using Arrays.stream()
  4. Filter it by calling filter(), so it only contains all the enum constants that equal the color you made (there should be either one or zero).
  5. Use toArray() to turn the stream into an array.
  6. Get the first element of that array with [0]. This will throw an ArrayIndexOutOfBoundsException if there isn't a predefined color matching your color.
  7. Get the name of that color with Enum's toString().
String colorName = Arrays.stream(Color.getClass().getDeclaredFields())
                         .filter(f -> f.get(null).equals(color))
                         .toArray()[0]
                         .toString();
The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
1

There is no set function for this kind of behavior, but you could do something like this:

public static String getColorName(int r, int g, int b) {
    String[] colorNames = new String[] {
            "BLACK",
            "BLUE",
            "GREEN",
            "CYAN",
            "DARK_GRAY",
            "GRAY",
            "LIGHT_GRAY",
            "MAGENTA",
            "ORANGE",
            "PINK",
            "RED",
            "WHITE",
            "YELLOW"
    };
    Color userProvidedColor = new Color(r,g,b);
    Color color;
    Field field;
    for (String colorName : colorNames) {
        try {
            field = Class.forName("java.awt.Color").getField(colorName);
            color = (Color)field.get(null);
            if (color.equals(userProvidedColor)) {
                return colorName; // Or maybe return colorName.toLowerCase() for aesthetics
            }
        } catch (Exception e) {

        }
    }
    Color someOtherCustomDefinedColorMaybePurple = new Color(128,0,128);
    if (someOtherCustomDefinedColorMaybePurple.equals(userProvidedColor)) {
        return "Purple";
    }
    return "Undefined";
}

There are a few options from here as well, maybe you want the nearest color? In which case you could try and resolve the distance somehow (here by distance from each r,g,b coordinate, admittedly not the best method but simple enough for this example, this wiki page has a good discussion on more rigorous methods)

// ...
String minColorName = "";
float minColorDistance = 10000000;
float thisColorDistance = -1;
for (String colorName : colorNames) {
    try {
        field = Class.forName("java.awt.Color").getField(colorName);
        color = (Color)field.get(null);
        thisColorDistance = ( Math.abs(color.red - userProvidedColor.red) + Math.abs(color.green - userProvidedColor.green) + Math.abs(color.blue - userProvidedColor.blue) );
        if (thisColorDistance < minColorDistance) {
            minColorName = colorName;
            minColorDistance = thisColorDistance;
        }
    } catch (Exception e) {
        // exception that should only be raised in the case color name is not defined, which shouldnt happen
    }
}
if (minColorName.length > 0) {
    return minColorName;
}
// Tests on other custom defined colors

This should outline how you would be able to compare to the built in colors from the Color library. You could use a Map to expand the functionality further to allow for you to define as many custom colors as you like (Something @TheGuywithTheHat suggests as well) which gives you more control over the return names of matched colors, and allows for you to go by more colors than just the predefined ones:

HashMap<String,Color> colorMap = new HashMap<String,Color>();

colorMap.put("Red",Color.RED);
colorMap.put("Purple",new Color(128,0,128));
colorMap.put("Some crazy name for a color", new Color(50,199,173));
// etc ...

String colorName;
Color color;
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
    colorName = entry.getKey();
    color= entry.getValue();
    // Testing against users color
}
Community
  • 1
  • 1
Farmer Joe
  • 6,020
  • 1
  • 30
  • 40
0

Without any helping libraries I would say: No. Especially because not every RGB-Color has a specific name. However, you could of course build an own function, which tries to match some of the available colors and deliver something like "Unknown" if there is no match.

The matching attempt could theoretically be done using the Java reflection API...

Neuron
  • 5,141
  • 5
  • 38
  • 59
nils
  • 1,362
  • 1
  • 8
  • 15
  • You could also attempt to resolve to the nearest available pre-defined color, but I agree that you'll have to implement this yourself. – jgitter Apr 28 '14 at 16:28
0

As far as i know, we don't have any such library to directly access the colors from the Constants.

But we can manage do it using Hex Color Library in Java.

References :

  1. Hex

  2. Color Class

Community
  • 1
  • 1
Sireesh Yarlagadda
  • 12,978
  • 3
  • 74
  • 76