在不使用java.awt.Color的情况下从HSV(Java中的HSB)转换为RGB(在Google App Engine上不允许)

我想我应该发布这个问题,即使我已经找到了解决方案,因为当我搜索它时,Java实现并不容易获得。

使用HSV代替RGB可以生成具有相同饱和度和亮度的颜色(我想要的东西)。

Google App Engine不允许使用java.awt.Color,因此执行以下操作以在HSV和RGB之间进行转换不是一个选项:

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

编辑:我按照尼克约翰逊的评论中的描述移动了我的答案。

前animo, – 亚历山大。

我对颜色数学一无所知,但我可以为代码提供这种替代结构,这让我的审美感觉更加刺激,因为它让我明白了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; } 

您应该使用Oracle提供的HSBtoRGB实现,将其源代码复制到您的项目中。 java.awt.Color是开源的。 Peter Recore和Yngling提供的算法不健全,并且对于某些输入将返回非法RGB值,如“256,256,0”。 Oracle的实现很强大,而是使用它。

我的转换代码:

  /** * @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)))); 

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

这里的舍入似乎是正确的。

解决方案在这里找到: 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; } 

使用提供的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

这是源代码 。

使用SWT,您可以使用以下代码段:

 RGB rgb = new RGB(r, g, b); float[] hsbColor = rgb.getHSB(); rgb = new RGB(hsbColor[0], hsbColor[1], hsbColor[2]); 
    Interesting Posts