简体   繁体   English

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

[英]Converting RGBA, HSL and HSLA colors to RGB (or in a java.awt.Color object)

I'm looking for a description of algorithms for converting RGBA, HSL and HSLA colors to RGB color, or a library for converting them in an java.awt.Color object. 我正在寻找用于将RGBA,HSL和HSLA颜色转换为RGB颜色的算法的描述,或者用于在java.awt.Color对象中转换它们的库。

Can you help me? 你能帮助我吗?

You can use Color.HSBtoRGB and Color.RGBtoHSB . 您可以使用Color.HSBtoRGBColor.RGBtoHSB For example: 例如:

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

This outputs: 这输出:

0.5
1.0
1.0

These three float values are the H, S, and B values respectively. 这三个float值分别是H,S和B值。 For colors with alpha, the alpha doesn't change from RGB to HSB, so A == A . 对于具有alpha的颜色,alpha不会从RGB更改为HSB,因此A == A

To create a Color with the returned array: 要使用返回的数组创建Color

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

I can't help you much more without more details about what exactly you want as input and output. 如果没有关于你想要什么作为输入和输出的更多细节,我无法帮助你。


Edit: See my other answer. 编辑:看到我的其他答案。

With the new info from the comments, I'll change this to reflect what you have versus what you need. 通过评论中的新信息,我将更改此信息以反映您所拥有的内容与您需要的内容。

First, we need to parse the rgb/hsl string. 首先,我们需要解析rgb / hsl字符串。 This can be done pretty easily using a couple regular expressions and String.split : 使用几个正则表达式和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);

The first Pattern matches any hex-encoded value. 第一个Pattern匹配任何十六进制编码的值。 The second one matches rgb(something) or rgba(something) . 第二个匹配rgb(something)rgba(something) The third one is the same as the second one, but with hsl and hsla . 第三个与第二个相同,但是使用hslhsla To use these: 要使用这些:

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

Here's what everything does: 以下是一切:

  • getRGB - Takes the CSS string, determines its format, then proceeds to parsing it. getRGB - 获取CSS字符串,确定其格式,然后继续解析它。 Returns null if it can't determine the format (ie, it's invalid). 如果无法确定格式(即,它无效),则返回null The array returned will be 4 elements, r, g, b, and a, and all values will be between 0 and 255. 返回的数组将是4个元素r,g,b和a,所有值都在0到255之间。
  • getRgbFromHex - Uses Integer.decode to parse it since this does # hex numbers for us, then uses Color to get the RGB values. getRgbFromHex -使用Integer.decode来分析它,因为这并#我们进制数,然后使用Color来获取RGB值。
  • getRgbFromRgb - Parses for the values from an rgb string (includes rgba ). getRgbFromRgb - 解析rgb字符串中的值(包括rgba )。 Splits the string on whitespace, commas, or parentheses, then parses each individual value and creates an array from them. 在空格,逗号或括号上拆分字符串,然后解析每个单独的值并从中创建一个数组。
  • getRgbFromHsl - Behaves similarly to getRgbFromRgb , but with HSL values and the appropriate parsing instead of the RGB parsing. getRgbFromHsl - 与getRgbFromRgb类似,但具有HSL值和适当的解析而不是RGB解析。
  • hslToRgb - This is your calculation logic that you said you've already done in your comments. hslToRgb - 这是您在评论中已经完成的计算逻辑。 Just calculate the int values of r, g, and b here from h, s, and l, and this method will work. 只需从h,s和l计算r,g和b的int值,这个方法就可以了。
  • parseValue - If it's a percentage, it returns the parsed percentage times the value of max , otherwise, it simply parses it as an int using Integer.parseInt . parseValue - 如果它是百分比,则返回解析的百分比乘以max的值,否则,它只是使用Integer.parseInt将其解析为int
  • parsePercent - Parses the integer part of the string and returns the value as a double divided by 100. parsePercent - 解析字符串的整数部分,并将值作为double除以100返回。
  • parseAlpha - Parses the alpha as a double and returns it times 255. parseAlpha - 将alpha解析为double并将其返回255。

Testing with rgb/rgba confirms that this works: 使用rgb / rgba进行测试证实这有效:

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

This prints: 这打印:

[255, 0, 204, 255]
[255, 0, 0, 255]
[255, 0, 0, 127]
[255, 0, 76, 127]

One other thing you may want to consider is using rounding instead of casting directly to int for the percentage stuff. 您可能要考虑的另一件事是使用舍入而不是直接转换为int来获取百分比。 This would improve the accuracy of the percentages. 这将提高百分比的准确性。

Let me know if you have any further questions. 如果您有任何其他问题,请与我们联系。

Your regex rules don't work fine, because they allow uncorrect string (such as "rgba(1000,500%,500%,2)" ) and deny correct form (such as "#fff" ). 您的正则表达式规则不能正常工作,因为它们允许不正确的字符串(例如“rgba(1000,500%,500%,2)”)并拒绝正确的表单(例如“#fff”)。

I wrote more strict and correct regex rules: 我写了更严格和正确的正则表达式规则:

    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*\\)$";

For rgba and hsla, my goal is to calculate the actual color displayed. 对于rgba和hsla,我的目标是计算显示的实际颜色。 So I was wondering if, given an rgba/hsla color and its background color, there's a way to "mix" them to calculate the displayed color... 所以我想知道,如果给出一个rgba / hsla颜色及其背景颜色,有一种方法可以“混合”它们来计算显示的颜色......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM