3

I want an RGB value when the colour name is given as input. The following code is working for some colors (I guess for primary colors like red) and failing for some others (like cyan and mauve):

import java.awt.Color;
import javax.swing.text.html.StyleSheet;

public class ColourTest {
    public static void main(String[] args) {
        StyleSheet s = new StyleSheet();
        String colourName = "RED";
        Color clr = s.stringToColor(colourName);
        int r = clr.getRed();
        int g = clr.getGreen();
        int b = clr.getBlue();
        System.out.println("red:" + r + " green :" + g + " blue:" + b);
    }
}

Is there another way to get the RGB values for the color names?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Prathyusha K
  • 41
  • 1
  • 3
  • 1
    Possible duplicate of [Java color code convert to color name](http://stackoverflow.com/questions/4126029/java-color-code-convert-to-color-name) – Developer Marius Žilėnas Feb 07 '17 at 11:22
  • @Willmore, the opposite not `code to name` but `name to code` ;) PS : That was one poor question, he would be hang for that know ;) – AxelH Feb 07 '17 at 11:26
  • 1
    Did you have a specific set of color or it could be any ? What is the accepted value, if you look at car industry, they have a strange palet of color name ;) – AxelH Feb 07 '17 at 11:27
  • @AxelH It could be any color. – Prathyusha K Feb 07 '17 at 11:40
  • Then you should search for an open database of some sort that could store EVERY color name possible or create your own merge multiple. There is 16777216 code of color different, I am sure there is always someone that will find a name for each ;) even sometimes two name for the same one. I suggest you to find some sort of restricted color enumeration that you want to support. – AxelH Feb 07 '17 at 11:44
  • @AxelH good catch. Retracted the vote :) – Developer Marius Žilėnas Feb 07 '17 at 12:03

3 Answers3

1

Here's what I have found in the javax.swing.text.html.CSS class:

/**
 * Convert a color string such as "RED" or "#NNNNNN" or "rgb(r, g, b)"
 * to a Color.
 */
static Color stringToColor(String str) {
  Color color;

  if (str == null) {
      return null;
  }
  if (str.length() == 0)
    color = Color.black;
  else if (str.startsWith("rgb(")) {
    color = parseRGB(str);
  }
  else if (str.charAt(0) == '#')
    color = hexToColor(str);
  else if (str.equalsIgnoreCase("Black"))
    color = hexToColor("#000000");
  else if(str.equalsIgnoreCase("Silver"))
    color = hexToColor("#C0C0C0");
  else if(str.equalsIgnoreCase("Gray"))
    color = hexToColor("#808080");
  else if(str.equalsIgnoreCase("White"))
    color = hexToColor("#FFFFFF");
  else if(str.equalsIgnoreCase("Maroon"))
    color = hexToColor("#800000");
  else if(str.equalsIgnoreCase("Red"))
    color = hexToColor("#FF0000");
  else if(str.equalsIgnoreCase("Purple"))
    color = hexToColor("#800080");
  else if(str.equalsIgnoreCase("Fuchsia"))
    color = hexToColor("#FF00FF");
  else if(str.equalsIgnoreCase("Green"))
    color = hexToColor("#008000");
  else if(str.equalsIgnoreCase("Lime"))
    color = hexToColor("#00FF00");
  else if(str.equalsIgnoreCase("Olive"))
    color = hexToColor("#808000");
  else if(str.equalsIgnoreCase("Yellow"))
    color = hexToColor("#FFFF00");
  else if(str.equalsIgnoreCase("Navy"))
    color = hexToColor("#000080");
  else if(str.equalsIgnoreCase("Blue"))
    color = hexToColor("#0000FF");
  else if(str.equalsIgnoreCase("Teal"))
    color = hexToColor("#008080");
  else if(str.equalsIgnoreCase("Aqua"))
    color = hexToColor("#00FFFF");
  else if(str.equalsIgnoreCase("Orange"))
    color = hexToColor("#FF8000");
  else
      color = hexToColor(str); // sometimes get specified without leading #
  return color;
}

Thus if you are passing any color which is not present in the code above, you will unfortunately get a NullPointerException

However, I have found a hack to solve your problem. Use this code:

public static void main(String[] args) {
    StyleSheet s = new StyleSheet();
    String colourName = "Cyan";
    Color clr = stringToColorCustom(colourName);
    int r = clr.getRed();
    int g = clr.getGreen();
    int b = clr.getBlue();
    System.out.println("red:" + r + " green :" + g + " blue:" + b);
}

static Color stringToColorCustom(String str) {
    Color color;

    if (str == null) {
        return null;
    }
    if (str.length() == 0)
        color = Color.black;
    else if (str.charAt(0) == '#')
        color = hexToColor(str);
    else if (str.equalsIgnoreCase("Black"))
        color = hexToColor("#000000");
    else if (str.equalsIgnoreCase("Silver"))
        color = hexToColor("#C0C0C0");
    else if (str.equalsIgnoreCase("Gray"))
        color = hexToColor("#808080");
    else if (str.equalsIgnoreCase("White"))
        color = hexToColor("#FFFFFF");
    else if (str.equalsIgnoreCase("Maroon"))
        color = hexToColor("#800000");
    else if (str.equalsIgnoreCase("Red"))
        color = hexToColor("#FF0000");
    else if (str.equalsIgnoreCase("Purple"))
        color = hexToColor("#800080");
    else if (str.equalsIgnoreCase("Fuchsia"))
        color = hexToColor("#FF00FF");
    else if (str.equalsIgnoreCase("Green"))
        color = hexToColor("#008000");
    else if (str.equalsIgnoreCase("Lime"))
        color = hexToColor("#00FF00");
    else if (str.equalsIgnoreCase("Olive"))
        color = hexToColor("#808000");
    else if (str.equalsIgnoreCase("Yellow"))
        color = hexToColor("#FFFF00");
    else if (str.equalsIgnoreCase("Navy"))
        color = hexToColor("#000080");
    else if (str.equalsIgnoreCase("Blue"))
        color = hexToColor("#0000FF");
    else if (str.equalsIgnoreCase("Teal"))
        color = hexToColor("#008080");
    else if (str.equalsIgnoreCase("Aqua"))
        color = hexToColor("#00FFFF");
    else if (str.equalsIgnoreCase("Orange"))
        color = hexToColor("#FF8000");
    else if (str.equalsIgnoreCase("Cyan")) // Add your color
        color = hexToColor("#00FFFF"); // Add the RGB
    else
        color = hexToColor(str); // Sometimes get specified
                                 // without a leading #
    return color;
}

static final Color hexToColor(String value) {
    String digits;
    int n = value.length();
    if (value.startsWith("#")) {
        digits = value.substring(1, Math.min(value.length(), 7));
    }
    else {
        digits = value;
    }
    String hstr = "0x" + digits;
    Color c;
    try {
        c = Color.decode(hstr);
    }
    catch (NumberFormatException nfe) {
        c = null;
    }
    return c;
}

In the above code I have created a custom stringToColorCustom method, and now I can add whatever colors I want in that method.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

I suggest to use the kind of a translation table via HashMap:

    HashMap<NamedColor, RgbColor> table = new HashMap<>();
    table.put(new NamedColor("red"), new RgbColor("#ff0000"));
    table.put(new NamedColor("blue"), new RgbColor("#0000ff"));

How the conversion works:

class ColorConverter {

    // If you need reverse color conversion you can use handy bidirectoinal
    // maps from http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/bidimap/DualHashBidiMap.html
    private HashMap<Color, RgbColor> table;

    public static RgbColor convert(NamedColor color) {
        return table.get(color);
    }

Adjust this outline to your needs.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Absolut
  • 1,220
  • 1
  • 9
  • 11
0

Easiest in javafx:

    import javafx.scene.paint.Color;
    Color color = Color.web("orange");
    System.out.printf("Color: %s, RGBA #%x%n", color, color.hashCode());

For java.awt.Color one can use (slow) reflection on all those constants define there:

private static Optional<java.awt.Color> color(String name) {
    try {
        Field field = java.awt.Color.class.getDeclaredField(name.toUpperCase());
        int modifiers = field.getModifiers();
        if (field.getType() == java.awt.Color.class && Modifier.isStatic(modifiers
                && Modifier.isPublic(modifiers))) {
            return Optional.of((java.awt.Color)field.get(null));
        }
    } catch (NoSuchFieldException e) {
    }
    return Optional.empty();
}

Here there are some problems with names using underscore (which were removed in javafx).

    System.out.println("RGBA " + color("orange")
            .map(c -> String.format("#%x", c.getRGB()))
            .orElse("(unknown)"));

Because of CSS support in java's HTML with color names, there should exist an other solution, but I have never sought.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138