在Java中将颜色名称转换为RGB值

3
当输入颜色名称时,我希望能够获得RGB值。以下代码对于某些颜色(我猜是基本颜色如红色)有效,但对于其他一些颜色(如青色和紫红色)则无效:
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);
    }
}

是否有另一种方法获取颜色名称的RGB值?


1
可能是Java颜色代码转换为颜色名称的重复问题。 - Developer Marius Žilėnas
@Willmore,相反的不是“代码到名称”,而是“名称到代码”;)附言:那是一个糟糕的问题,他现在会被挂起来的;) - AxelH
1
你有特定的颜色集吗?还是可以任意选择?如果看看汽车行业,他们有一些奇怪的颜色名称,那么接受的值是什么? - AxelH
@AxelH 它可以是任何颜色。 - Prathyusha K
然后,您应该搜索一种可以存储所有可能颜色名称的开放数据库,或者创建自己的合并多个数据库。有16777216种不同的颜色代码,我相信总会有人为每种颜色找到一个名称;甚至有时候同一种颜色可能会有两个名称。我建议您找到一种受限制的颜色枚举,以便支持您想要的颜色。 - AxelH
@AxelH 很好的发现。撤回了投票 :) - Developer Marius Žilėnas
3个回答

1

我在javax.swing.text.html.CSS类中找到了以下内容:

/**
 * 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;
}

因此,如果您传递的颜色不在上面的代码中,您将不幸地遇到一个NullPointerException

然而,我发现了一个解决问题的技巧。使用以下代码:

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;
}

在上面的代码中,我创建了一个自定义的stringToColorCustom方法,现在我可以在该方法中添加任何颜色。

谢谢。我会尝试这个。 - Prathyusha K
这正是在javax.swing.text.html.CSS类中所写的方式。我已经反编译了JAR并调整了代码以适应更多的颜色。欢迎您提出改进代码的建议。 - Sourav Purakayastha

0
我建议使用HashMap来实现翻译表:
    HashMap<NamedColor, RgbColor> table = new HashMap<>();
    table.put(new NamedColor("red"), new RgbColor("#ff0000"));
    table.put(new NamedColor("blue"), new RgbColor("#0000ff"));

转换的工作原理:

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);
    }

根据您的需求调整此大纲。


0

在JavaFX中最简单的方法:

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

对于java.awt.Color,可以使用(较慢的)反射来定义其中所有常量:

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();
}

这里有一些使用下划线命名的问题(在JavaFX中已经被删除)。

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

由于Java的HTML支持使用颜色名称的CSS,应该存在另一种解决方案,但我从未寻找过。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接