将RGBA,HSL和HSLA颜色转换为RGB(或在java.awt.Color对象中)

时间:2012-09-11 15:59:04

标签: java css rgb rgba hsl

我正在寻找将RGBA,HSL和HSLA颜色转换为RGB颜色的算法的描述,或者用于在java.awt.Color对象中转换它们的库。

你能帮助我吗?

3 个答案:

答案 0 :(得分:2)

您可以使用Color.HSBtoRGBColor.RGBtoHSB。例如:

int r = 0, g = 255, b = 255;
float[] hsb = Color.RGBtoHSB(r, g, b, null);
for (float f : hsb) {
    System.out.println(f);
}

输出:

0.5
1.0
1.0

这三个float值分别是H,S和B值。对于具有alpha的颜色,alpha不会从RGB更改为HSB,因此A == A

使用返回的数组创建Color

Color color = Color.getHSBColor(hsb[0], hsb[1], hsb[2]);

如果没有更多关于您想要输入和输出的详细信息,我无法帮助您。


编辑:查看我的其他答案。

答案 1 :(得分:1)

根据评论中的新信息,我会对此进行更改以反映您所拥有的内容与您需要的内容。

首先,我们需要解析rgb / hsl字符串。使用几个正则表达式和String.split

可以非常轻松地完成此操作
private static final Pattern hexRegex = Pattern.compile("#[\\dA-Fa-f]{6}");
private static final Pattern rgbRegex = Pattern.compile("rgba?\\([^)]*\\)", Pattern.CASE_INSENSITIVE);
private static final Pattern hlsRegex = Pattern.compile("hlsa?\\([^)]*\\)", Pattern.CASE_INSENSITIVE);

第一个Pattern匹配任何十六进制编码的值。第二个匹配rgb(something)rgba(something)。第三个与第二个相同,但hslhsla。要使用这些:

public static int[] getRGB(String cssString) {
    if (hexRegex.matcher(cssString).matches())
        return getRgbFromHex(cssString);
    if (rgbRegex.matcher(cssString).matches())
        return getRgbFromRgb(cssString);
    if (hslRegex.matcher(cssString).matches())
        return getRgbFromHsl(cssString);
    return null; // no match
}

private static int[] getRgbFromHex(String hexString) {
    int rgb = Integer.decode(hexString);
    Color c = new Color(rgb);
    return new int[] { c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha() };
}

private static int[] getRgbFromRgb(String rgbString) {
    String[] values = rgbString.split("[\\s,()]");
    // values[0] is just "rgb" or "rgba"
    String red = values[1];
    String green = values[2];
    String blue = values[3];
    String alpha = "1.0";
    if (values.length >= 5) {
        alpha = values[4];
    }
    return new int[] {
        parseValue(red, 255),
        parseValue(green, 255),
        parseValue(blue, 255),
        parseAlpha(alpha),
    };
}

private static int[] getRgbFromHsl(String hslString) {
    String[] values = hslString.split("[\\s,()]");
    // values[0] is just "hsl" or "hsla"
    String hue = values[1];
    String sat = values[2];
    String light = values[3];
    String alpha = "1.0";
    if (values.length >= 5) {
        alpha = values[4];
    }
    int h = parseValue(hue, 360);
    double s = parsePercent(sat);
    double l = parsePercent(light);
    int a = parseAlpha(alpha);
    return hslToRgb(h, s, l, a);
}

private static int[] hslToRgb(int h, double s, double l, int a) {
    // TODO Calculate me
    int r = 0;
    int g = 0;
    int b = 0;
    return new int[] { r, g, b, a };
}

private static int parseValue(String val, int max) {
    if (val.endsWith("%")) {
        return (int) (parsePercent(val) * max);
    }
    return Integer.parseInt(val);
}

private static double parsePercent(String perc) {
    return Integer.parseInt(perc.substring(0, perc.length() - 1)) / 100.0;
}

private static int parseAlpha(String alpha) {
    return (int) (Double.parseDouble(alpha) * 255);
}

以下是一切:

  • getRGB - 获取CSS字符串,确定其格式,然后继续解析它。如果无法确定格式(即,它无效),则返回null。返回的数组将是4个元素r,g,b和a,所有值都在0到255之间。
  • getRgbFromHex - 使用Integer.decode来解析它,因为这为我们提供了#十六进制数字,然后使用Color来获取RGB值。
  • getRgbFromRgb - 解析rgb字符串中的值(包括rgba)。在空格,逗号或括号上拆分字符串,然后解析每个单独的值并从中创建一个数组。
  • getRgbFromHsl - 与getRgbFromRgb的行为类似,但使用HSL值和适当的解析而不是RGB解析。
  • hslToRgb - 这是您在评论中已经说过的计算逻辑。只需从h,s和l计算r,g和b的int值,这个方法就可以了。
  • parseValue - 如果它是百分比,则返回解析后的百分比乘以max的值,否则,只需使用{{1}将其解析为int }。
  • Integer.parseInt - 解析字符串的整数部分,并将值返回为parsePercent除以100。
  • double - 将alpha解析为parseAlpha并将其返回255次。

使用rgb / rgba进行测试证实这有效:

double

打印:

public static void main(String[] args) {
    System.out.println(Arrays.toString(getRGB("#FF00CC")));
    System.out.println(Arrays.toString(getRGB("rgb(255,0,0)")));
    System.out.println(Arrays.toString(getRGB("rgba(255,0,0,0.5)")));
    System.out.println(Arrays.toString(getRGB("rgba(100%,0%,30%,0.5)")));
}

您可能要考虑的另一件事是使用舍入而不是直接转换为[255, 0, 204, 255] [255, 0, 0, 255] [255, 0, 0, 127] [255, 0, 76, 127] 百分比。这样可以提高百分比的准确性。

如果您有任何其他问题,请与我们联系。

答案 2 :(得分:1)

你的正则表达式规则不正常,因为它们允许不正确的字符串(例如“rgba(1000,500%,500%,2)”)并拒绝正确的形式(例如“#fff”)。

我写了更严格和正确的正则表达式规则:

    String keywords_color_regex = "^[a-z]*$";
    String hex_color_regex = "^#[0-9a-f]{3}([0-9a-f]{3})?$";
    String rgb_color_regex = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$";
    String rgba_color_regex = "^rgba\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*((0.[1-9])|[01])\\s*\\)$";
    String hsl_color_regex = "^hsl\\(\\s*(0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*\\)$";

对于rgba和hsla,我的目标是计算显示的实际颜色。所以我想知道,如果给出一个rgba / hsla颜色及其背景颜色,有一种方法可以“混合”它们来计算显示的颜色...