10

Java 実装を検索したときにすぐに利用できなかったので、既に解決策を見つけていたとしても、この質問を投稿する必要があると考えました。

RGB の代わりに HSV を使用すると、同じ彩度と明るさ (私が望んでいたもの) の色を生成できます。

Google App Engine では java.awt.Color の使用が許可されていないため、次のようにして HSV と RGB を変換することはできません。

Color c = Color.getHSBColor(hue, saturation, value);
String rgb = Integer.toHexString(c.getRGB());

編集:ニック・ジョンソンのコメントに記載されているように、回答を移動しました。

Ex animo、 - アレクサンダー。

4

7 に答える 7

19

私は色の計算について何も知りませんが、このコードの代替構造を提供できます。これは、6 つのケースのそれぞれが、値 t と p の異なる順列であることを明らかにしたので、私の美的感覚をくすぐります。 . (また、長い if-else チェーンに対する不合理な恐怖もあります。)

public static String hsvToRgb(float hue, float saturation, float value) {

    int h = (int)(hue * 6);
    float f = hue * 6 - h;
    float p = value * (1 - saturation);
    float q = value * (1 - f * saturation);
    float t = value * (1 - (1 - f) * saturation);

    switch (h) {
      case 0: return rgbToString(value, t, p);
      case 1: return rgbToString(q, value, p);
      case 2: return rgbToString(p, value, t);
      case 3: return rgbToString(p, q, value);
      case 4: return rgbToString(t, p, value);
      case 5: return rgbToString(value, p, q);
      default: throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
    }
}

public static String rgbToString(float r, float g, float b) {
    String rs = Integer.toHexString((int)(r * 256));
    String gs = Integer.toHexString((int)(g * 256));
    String bs = Integer.toHexString((int)(b * 256));
    return rs + gs + bs;
}
于 2011-10-26T04:17:51.140 に答える
5

Oracle が提供する HSBtoRGB 実装を使用して、そのソース コードをプロジェクトにコピーする必要があります。java.awt.Color はオープンソースです。Peter Recore と Yngling が提供するアルゴリズムは堅牢ではなく、特定の入力に対して "256,256,0" のような不正な RGB 値を返します。Oracle の実装は堅牢です。代わりにそれを使用してください。

于 2013-09-24T20:37:48.330 に答える
5

を提供するColorUtilsを使用します。

HSLToColor(float\[\] hsl) 

[RGBToHSL(int r, int g, int b, float\[\] hsl)]

相互に変換するのが非常に簡単なメソッド!

例えば:

float[] hsl = new float[]{1.5, 2.0, 1.5};
int color = ColorUtils.HSLToColor(hsl);

今すぐ色を取得します

float[] hslStub = new float[3];
float[] hslFromColor = ColorUtils.colorToHSL(color, hslStub);

hslを取得します

これがソースコードです。

于 2015-08-10T08:39:08.243 に答える
2

解決策はここにあります: http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

Martin Ankerl は、この件に関して優れた投稿を提供し、Ruby スクリプトを提供しています。Java で実装するのに忙しすぎる (または怠惰な) 人のために、私が行ったものを次に示します (もっと効果的に記述できると確信しています。お気軽にコメントしてください)。

public static String hsvToRgb(float hue, float saturation, float value) {
    float r, g, b;

    int h = (int)(hue * 6);
    float f = hue * 6 - h;
    float p = value * (1 - saturation);
    float q = value * (1 - f * saturation);
    float t = value * (1 - (1 - f) * saturation);

    if (h == 0) {
        r = value;
        g = t;
        b = p;
    } else if (h == 1) {
        r = q;
        g = value;
        b = p;
    } else if (h == 2) {
        r = p;
        g = value;
        b = t;
    } else if (h == 3) {
        r = p;
        g = q;
        b = value;
    } else if (h == 4) {
        r = t;
        g = p;
        b = value;
    } else if (h <= 6) {
        r = value;
        g = p;
        b = q;
    } else {
        throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
    }

    String rs = Integer.toHexString((int)(r * 255));
    String gs = Integer.toHexString((int)(g * 255));
    String bs = Integer.toHexString((int)(b * 255));
    return rs + gs + bs;
}
于 2011-10-26T10:57:52.000 に答える
1

変換するための私のコード:

     /**
     * @param H
     *            0-360
     * @param S
     *            0-100
     * @param V
     *            0-100
     * @return color in hex string
     */
    public static String hsvToRgb(float H, float S, float V) {

        float R, G, B;

        H /= 360f;
        S /= 100f;
        V /= 100f;

        if (S == 0)
        {
            R = V * 255;
            G = V * 255;
            B = V * 255;
        } else {
            float var_h = H * 6;
            if (var_h == 6)
                var_h = 0; // H must be < 1
            int var_i = (int) Math.floor((double) var_h); // Or ... var_i =
                                                            // floor( var_h )
            float var_1 = V * (1 - S);
            float var_2 = V * (1 - S * (var_h - var_i));
            float var_3 = V * (1 - S * (1 - (var_h - var_i)));

            float var_r;
            float var_g;
            float var_b;
            if (var_i == 0) {
                var_r = V;
                var_g = var_3;
                var_b = var_1;
            } else if (var_i == 1) {
                var_r = var_2;
                var_g = V;
                var_b = var_1;
            } else if (var_i == 2) {
                var_r = var_1;
                var_g = V;
                var_b = var_3;
            } else if (var_i == 3) {
                var_r = var_1;
                var_g = var_2;
                var_b = V;
            } else if (var_i == 4) {
                var_r = var_3;
                var_g = var_1;
                var_b = V;
            } else {
                var_r = V;
                var_g = var_1;
                var_b = var_2;
            }

            R = var_r * 255; // RGB results from 0 to 255
            G = var_g * 255;
            B = var_b * 255;
        }

        String rs = Integer.toHexString((int) (R));
        String gs = Integer.toHexString((int) (G));
        String bs = Integer.toHexString((int) (B));

        if (rs.length() == 1)
            rs = "0" + rs;
        if (gs.length() == 1)
            gs = "0" + gs;
        if (bs.length() == 1)
            bs = "0" + bs;
        return "#" + rs + gs + bs;
    }

Android での使用例:

tv.setBackgroundColor(Color.parseColor((ColorOperations.hsvToRgb(100, 100, 57))));
于 2014-09-21T22:47:34.517 に答える
1

SWT を使用すると、次のコード スニペットを使用できます。

RGB rgb = new RGB(r, g, b);
float[] hsbColor = rgb.getHSB();
rgb = new RGB(hsbColor[0], hsbColor[1], hsbColor[2]);
于 2016-05-19T07:36:03.450 に答える
1

@Peter Recore による回答では、丸めは使用されません。

おそらく、それを使用するより正しい方法は、java.awt.Color からコンテンツをコピーすることです。これは、Java 6 での外観です。

 public static int HSBtoRGB(float hue, float saturation, float brightness) {
        int r = 0, g = 0, b = 0;
        if (saturation == 0) {
            r = g = b = (int) (brightness * 255.0f + 0.5f);
        } else {
            float h = (hue - (float)Math.floor(hue)) * 6.0f;
            float f = h - (float)java.lang.Math.floor(h);
            float p = brightness * (1.0f - saturation);
            float q = brightness * (1.0f - saturation * f);
            float t = brightness * (1.0f - (saturation * (1.0f - f)));
            switch ((int) h) {
            case 0:
                r = (int) (brightness * 255.0f + 0.5f);
                g = (int) (t * 255.0f + 0.5f);
                b = (int) (p * 255.0f + 0.5f);
                break;
            case 1:
                r = (int) (q * 255.0f + 0.5f);
                g = (int) (brightness * 255.0f + 0.5f);
                b = (int) (p * 255.0f + 0.5f);
                break;
            case 2:
                r = (int) (p * 255.0f + 0.5f);
                g = (int) (brightness * 255.0f + 0.5f);
                b = (int) (t * 255.0f + 0.5f);
                break;
            case 3:
                r = (int) (p * 255.0f + 0.5f);
                g = (int) (q * 255.0f + 0.5f);
                b = (int) (brightness * 255.0f + 0.5f);
                break;
            case 4:
                r = (int) (t * 255.0f + 0.5f);
                g = (int) (p * 255.0f + 0.5f);
                b = (int) (brightness * 255.0f + 0.5f);
                break;
            case 5:
                r = (int) (brightness * 255.0f + 0.5f);
                g = (int) (p * 255.0f + 0.5f);
                b = (int) (q * 255.0f + 0.5f);
                break;
            }
        }
        return 0xff000000 | (r << 16) | (g << 8) | (b << 0);
    }

ここでの丸めは正しいようです。

于 2015-07-04T11:10:11.993 に答える