Converting from HSV (HSB in Java) to RGB without using java.awt.Color (disallowed on Google App Engine)

yngling picture yngling · Oct 25, 2011 · Viewed 35.1k times · Source

I figured I should post this question, even if I have already found a solution, as a Java implementation was not readily available when I searched for it.

Using HSV instead of RGB allows the generation of colors with the same saturation and brightness (something I wanted).

Google App Engine does not allow use of java.awt.Color, so doing the following to convert between HSV and RGB is not an option:

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

Edit: I moved my answer as described in the comment by Nick Johnson.

Ex animo, - Alexander.

Answer

Peter Recore picture Peter Recore · Oct 26, 2011

I don't know anything about color math, but I can offer this alternative structure for the code, which tickles my aesthetic sense because it made it obvious to me how each of the 6 cases is just a different permutation of value, t and p. (Also I have an irrational fear of long if-else chains.)

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