2

So I have the following method for generating random colours that I use in my application:

public final Color generateRandomColour() {

    return Color.getHSBColor(new Random().nextFloat(),
            new Random().nextFloat(), new Random().nextFloat());
}

I get a range of different colours, but as I'm using these colours to paint "rectangles" in Swing on a background with light colours, I'm interested in generating colours which are relatively dark. The background is a light grey so sometimes the generated random colours are also light grey which makes it hard to see the rectangles.

I've tried to put a cap on the max float values but it doesn't seem to get me darker colours only. Any help appreciated.

Force444
  • 3,321
  • 9
  • 39
  • 77
  • 1
    See http://stackoverflow.com/questions/6396201/how-do-i-generate-random-dark-colors-in-c – home Feb 18 '13 at 09:13

6 Answers6

3

You might try:

public final Color generateDarkColor() {
  return generateRandomColour().darker();
}

See also http://docs.oracle.com/javase/6/docs/api/java/awt/Color.html#darker()

Afshin Moazami
  • 2,092
  • 5
  • 33
  • 55
Burkhard
  • 14,596
  • 22
  • 87
  • 108
3

This seems to work. Note to use the same instance of Random! The 1st image limits the B of the HSB to .5f, while 2nd image shows the effect of using Color.darker() instead.

Image HSB Color.darker()

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.Random;
import java.util.logging.*;
import javax.imageio.ImageIO;
import java.io.*;

class DarkHSB {

    float darker = .5f;
    Random r = new Random();

    public final Color generateRandomColor(boolean useHsbApi) {
        float brightness = (useHsbApi ? r.nextFloat() * darker : r.nextFloat());
        // Random objects created sequentially will have the same seed!
        Color c = Color.getHSBColor(
                r.nextFloat(),
                r.nextFloat(),
                brightness);
        if (!useHsbApi) c = c.darker();
        return c;
    }

    public void paint(Graphics g, int x, int y, int w, int h, boolean useApi) {
        g.setColor(generateRandomColor(useApi));
        g.fillRect(x,y,w,h);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                final JPanel gui = new JPanel(new GridLayout(0,1));

                final DarkHSB dhsb = new DarkHSB();
                int w = 300;
                int h = 100;

                BufferedImage hsb = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
                Graphics g = hsb.getGraphics();
                int sz = 5;
                for (int xx=0; xx<w; xx+=sz) {
                    for (int yy=0; yy<h; yy+=sz) {
                        dhsb.paint(g,xx,yy,sz,sz,true);
                    }
                }
                g.dispose();

                BufferedImage darker = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
                g = darker.getGraphics();
                for (int xx=0; xx<w; xx+=sz) {
                    for (int yy=0; yy<h; yy+=sz) {
                        dhsb.paint(g,xx,yy,sz,sz,false);
                    }
                }
                g.dispose();

                gui.add(new JLabel(new ImageIcon(hsb)));
                gui.add(new JLabel(new ImageIcon(darker)));

                JOptionPane.showMessageDialog(null, gui);

                File userHome = new File(System.getProperty("user.home"));
                File img = new File(userHome,"image-hsb.png");
                dhsb.saveImage(hsb,img);
                img = new File(userHome,"image-darker.png");
                dhsb.saveImage(darker,img);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }

    public void saveImage(BufferedImage bi, File file) {
        try {
            ImageIO.write(bi, "png", file);
        } catch (IOException ex) {
            Logger.getLogger(DarkHSB.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
0

You could use % :

new Random().nextFloat() % maxValue;

Edit: Didn't see you are using HSB (Hue Saturation Brightness). Just decreasing the last value should be enough.

Michael Laffargue
  • 10,116
  • 6
  • 42
  • 76
0

Try to generate your colour coordingates in another colour space, then transform to RGB. Is suggest you use LAB Color space. If you keep you L low then you get dark colours.

I've not checked but it looks like the conversion to RBG can be done by the ColorSpace class in the JDK.

David Roussel
  • 5,788
  • 1
  • 30
  • 35
0

i never used hsb model, but third value in HSB model is brightness so all waht you need to do is limit range of third value. this depends on how dark colours you want.

user902383
  • 8,420
  • 8
  • 43
  • 63
0

This should generate colours which are relatively dark.

    Random r = new Random();
    Color c = new Color(r.nextInt(100),r.nextInt(100),r.nextInt(100));
Fiachra
  • 125
  • 1
  • 2
  • 9