Skip to content

Instantly share code, notes, and snippets.

@calebegg
Last active December 13, 2015 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calebegg/4942742 to your computer and use it in GitHub Desktop.
Save calebegg/4942742 to your computer and use it in GitHub Desktop.
Code used to automatically generate some wallpapers I use. Here are four examples: http://imgur.com/a/7b7z2
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
class Wallpaper extends JComponent {
private final int SIZE = 40;
private Color[][][] colors = new Color[SIZE][SIZE][2];
private boolean[][] orient = new boolean[SIZE][SIZE];
private float hue1, hue2;
private final int width;
private final int height;
public Wallpaper(int width, int height) {
this.width = width;
this.height = height;
setPreferredSize(new Dimension(1366, 768));
generateWallpaper();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
generateWallpaper();
repaint();
}
});
}
public void generateWallpaper() {
colors = new Color[SIZE][SIZE][2];
Random rng = new Random();
float hueDiff = .3f;
hue1 = rng.nextFloat() * (1 - hueDiff);
hue2 = hue1 + rng.nextFloat() * hueDiff;
int randomFactor = 4; // Higher for more similarity along the row or column.
final float satLowerBound = .2f;
for (int i = 0; i < SIZE; i++) {
float[] sats = new float[] { rng.nextFloat(), rng.nextFloat() };
float[] lums = new float[] { rng.nextFloat(), rng.nextFloat() };
for (int j = 0; j < SIZE; j++) {
for (int k = 0; k < 2; k++) {
// Do this twice; once for row x, and once for column x.
boolean b = k == 0;
int x, y;
if (b) {
x = i;
y = j;
} else {
x = j;
y = i;
}
Color oldColor = colors[x][y][0];
Color newColor = Color.getHSBColor(b ? hue1 : hue2, sats[k], lums[k]);
newColor = average(oldColor, newColor);
colors[x][y][0] = newColor;
float[] newParts = Color.RGBtoHSB(newColor.getRed(), newColor.getGreen(),
newColor.getBlue(),
new float[3]);
float newLum = newParts[2];
// Other half of square has same hue + sat, but slightly different
// brightness.
colors[x][y][1] = Color.getHSBColor(newParts[0], newParts[1],
newLum + (newLum > .5 ? -.1f : .1f));
sats[k] += rng.nextFloat() / randomFactor - .5 / randomFactor;
lums[k] += rng.nextFloat() / randomFactor - .5 / randomFactor;
// Sat and lum values should be bounded.
if (sats[k] > 1) sats[k] = 1;
if (sats[k] < satLowerBound) sats[k] = satLowerBound;
if (lums[k] > 1) lums[k] = 1;
if (lums[k] < 0) lums[k] = 0;
}
orient[j][i] = rng.nextBoolean();
}
}
}
private Color average(Color a, Color b) {
// Combines two colors in a reasonable way; weighted average of hues,
// average saturation, and the max brightness.
if (a == null) return b;
if (b == null) return a;
float[] aComp = new float[3];
float[] bComp = new float[3];
Color.RGBtoHSB(a.getRed(), a.getGreen(), a.getBlue(), aComp);
Color.RGBtoHSB(b.getRed(), b.getGreen(), b.getBlue(), bComp);
float aHue = aComp[0];
float bHue = bComp[0];
float aSat = aComp[1];
float bSat = bComp[1];
float newHue = (aHue * aSat + bHue * bSat) / (aSat + bSat); // Average, weighted by sat
if (newHue > 1) newHue = 1;
return Color.getHSBColor(newHue,
(aSat + bSat) / 2, Math.max(aComp[2], bComp[2]));
}
@Override public void paintComponent(Graphics gOld) {
Graphics2D g = (Graphics2D) gOld;
int maxdim = Math.max(width, height);
int spacing = maxdim * 2 / SIZE;
g.translate(maxdim / 2, -maxdim / 2);
g.rotate(Math.PI / 4);
for (int r = 0; r < SIZE; r++) {
for (int c = 0; c < SIZE; c++) {
int top = r * spacing;
int bottom = (r + 1) * spacing;
int left = c * spacing;
int right = (c + 1) * spacing;
g.setColor(colors[r][c][0]);
g.fillPolygon(new int[] {left, left, right},
new int[] {top, bottom, orient[r][c] ? bottom : top}, 3);
g.setColor(colors[r][c][1]);
g.fillPolygon(new int[] {left, right, right},
new int[] {orient[r][c] ? top : bottom, top, bottom}, 3);
}
}
g.rotate(-Math.PI / 4);
g.translate(-maxdim / 2, maxdim / 2);
// Paint some swatches of the fully-saturated hues used to generate this wall.
// g.setColor(Color.getHSBColor(hue1, 1, 1));
// g.fill(new Ellipse2D.Double(0, 0, 30, 30));
// g.setColor(Color.getHSBColor(hue2, 1, 1));
// g.fill(new Ellipse2D.Double(0, 30, 30, 30));
}
}
public class Main {
private static boolean GENERATE_FILES = false;
public static void main(String[] args) {
int width = 1366;
int height = 768;
Wallpaper w = new Wallpaper(width, height);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
if (GENERATE_FILES) {
try {
for (int i = 0; i < 50; i++) {
w.generateWallpaper();
w.paintComponent(bi.getGraphics());
ImageIO.write(bi, "png", new File("wallpaper_" + i + ".png"));
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
JFrame f = new JFrame("Wallpaper");
f.add(w);
f.pack();
f.setVisible(true);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment