Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate different colors of same luminance for line chart in Java?

I want to generate different colors for my line graphs:

  • I want to generate equally different colors (for human eye)
  • I want them to be the same luminance (not computed brightness)

(this rules out RGB and HSL, YIQ is close but has not perfectly uniform luminance)

Have you used any libraries (in Java) to handle uniform color scheme generation?

I've spent a few days on this issue already, so I'm hoping some of you had the same problem and solved it.

Thanks!

Edit: unfortunately, I cannot use java.awt packages on AppEngine (or anything that uses java.awt.Color).

like image 308
hakunin Avatar asked Jan 31 '11 09:01

hakunin


1 Answers

Here's a little function I wrote just now from looking at the Wikipedia page http://en.wikipedia.org/wiki/SRGB_color_space

private int makeARGB(double Y, double x, double y) {
  // Out of gamut colour
  int rgb = 0xFF808080;
  double X = Y * x / y;
  double Z = Y * (1 - x - y) / y;
  double rlin = +3.2046 * X + -1.5372 * Y + -0.4986 * Z;
  double r = gamma(rlin);
  int ir = (int) (r * 255.0);
  if (ir >= 0 && ir < 256) {
    double glin = -0.9689 * X + +1.8758 * Y + +0.0415 * Z;
    double g = gamma(glin);
    int ig = (int) (g * 255.0);
    if (ig >= 0 && ig < 256) {
      double blin = +0.0557 * X + -0.2040 * Y + +1.0570 * Z;
      double b = gamma(blin);
      int ib = (int) (b * 255.0);
      if (ib >= 0 && ib < 256) {
        rgb = 0xFF000000 + (ir << 16) + (ig << 8) + (ib << 0);
      }
    }
  }
  return rgb;
}
private double gamma(double l) {
  if (l < 0.0031308) {
    return l * 12.92;
  } else {
    return 1.055 * Math.pow(l, 1.0 / 2.4) - 0.055;
  }
}
private BufferedImage createImage() {
    BufferedImage bm = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
    for (int ix = 0; ix < bm.getWidth(); ++ix) {
        double astar = ((double) ix) / ((double) bm.getWidth());
        for (int iy = 1; iy < bm.getHeight(); ++iy) {
            double bstar = ((double) iy) / ((double) bm.getHeight());
            int rgb = makeARGB(0.3, astar, bstar);
            bm.setRGB(ix, iy, rgb);
        }

    }
    return bm;
}

You pass in a luminance Y and colour coordinates x,y. x and y are nominally from 0..1 but a lot of that 'space' is not in the sRGB gamut so doesn't correspond to a displayable colour. Y is also 0..1, try 0.3..0.5 initially.

An example image:gamut with Y=0.3

I don't know anything about google app engine but is an ARGB integer the kind of colour specification you need?

like image 174
Peter Hull Avatar answered Oct 23 '22 14:10

Peter Hull