1

RGBA、HSL、および HSLA カラーを RGB カラーに変換するためのアルゴリズムの説明、または java.awt.Color オブジェクトでそれらを変換するためのライブラリを探しています。

手伝って頂けますか?

4

3 に答える 3

3

コメントからの新しい情報を使用して、これを変更して、あなたが持っているものと必要なものを反映させます.

まず、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);

1 つ目Patternは、16 進数でエンコードされた値に一致します。rgb(something)2 番目のものはorに一致しrgba(something)ます。3 番目のものは 2 番目のものと同じですが、 と がhslありhslaます。これらを使用するには:

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フォーマットを判別できない場合 (つまり、無効な場合) を返します。返される配列は r、g、b、a の 4 つの要素で、すべての値は 0 ~ 255 です。
  • getRgbFromHex-これは16 進数をInteger.decode処理するため、解析に使用し、次にRGB 値の取得に使用します。#Color
  • getRgbFromRgbrgb-文字列 ( を含む)から値を解析しますrgba。空白、コンマ、または括弧で文字列を分割し、個々の値を解析して、それらから配列を作成します。
  • getRgbFromHsl- と同様に動作しgetRgbFromRgbますが、RGB 解析の代わりに HSL 値と適切な解析を使用します。
  • hslToRgb- これは、コメントで既に実行済みであると述べた計算ロジックです。intここで、h、s、および l から r、g、および bの値を計算するだけで、この方法は機能します。
  • parseValue- パーセンテージの場合は、解析されたパーセンテージに の値を掛けた値を返しますmax。それ以外の場合は、単にintusingとして解析しInteger.parseIntます。
  • parsePercentdouble- 文字列の整数部分を解析し、値を100 で割った値として返します。
  • parseAlpha- アルファを として解析し、double255 倍して返します。

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

これは以下を出力します:

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

考慮したいもう1つのことはint、パーセンテージのものに直接キャストする代わりに丸めを使用することです。これにより、パーセンテージの精度が向上します。

ご不明な点がございましたら、お気軽にお問い合わせください。

于 2012-09-12T16:28:22.320 に答える
2

Color.HSBtoRGBとを使用できますColor.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

これら 3 つのfloat値は、それぞれ H、S、および B の値です。アルファ付きの色の場合、アルファは RGB から HSB に変化しないため、A == A.

Color返された配列でを作成するには:

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

入力と出力として正確に何が必要かについての詳細がなければ、これ以上のことはできません。


編集:私の他の答えを見てください。

于 2012-09-11T17:51:09.733 に答える
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の色とその背景色が与えられた場合、それらを「混ぜて」表示される色を計算する方法があるかどうか疑問に思っていました...

于 2012-09-17T09:24:05.070 に答える