【问题标题】:Convert colour names to RGB values in Java在 Java 中将颜色名称转换为 RGB 值
【发布时间】:2017-06-24 14:50:39
【问题描述】:

当颜色名称作为输入时,我想要一个 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 值吗?

【问题讨论】:

  • @Willmore,相反的不是code to name,而是name to code ;) PS:这是一个糟糕的问题,他会被绞死的;)
  • 您是否有特定的颜色集或者可以是任何颜色?什么是公认的价值,如果你看看汽车行业,他们有一个奇怪的颜色名称;)
  • @AxelH 可以是任何颜色。
  • 然后您应该搜索某种开放式数据库,该数据库可以存储所有可能的颜色名称或创建您自己的合并倍数。有 16777216 种不同颜色的代码,我相信总有人会为每个人找到一个名字;)甚至有时同一个名字有两个名字。我建议您找到某种您想要支持的受限颜色枚举。

标签: java


【解决方案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 方法,现在我可以在该方法中添加我想要的任何颜色。

【讨论】:

  • 谢谢。我会试试这个。
  • 这正是javax.swing.text.html.CSS类中的写法。我已经反编译了 JAR 并调整了代码以适应更多颜色。欢迎您提出改进代码的建议。
【解决方案2】:

我建议通过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);
    }

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

【讨论】:

    【解决方案3】:

    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 支持带有颜色名称,应该存在其他解决方案,但我从未寻求过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      • 2013-12-10
      • 2012-03-30
      • 1970-01-01
      • 2017-10-28
      • 2013-12-05
      • 2013-08-04
      相关资源
      最近更新 更多