Initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/.git/
|
||||||
|
/.idea/
|
||||||
|
/out/
|
||||||
|
/task/
|
||||||
|
*.iml
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: fr.klemek.marble.WallpaperGenerator
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class Color {
|
||||||
|
final byte r;
|
||||||
|
final byte g;
|
||||||
|
final byte b;
|
||||||
|
|
||||||
|
Color(byte r, byte g, byte b) {
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color(int r, int g, int b) {
|
||||||
|
this.r = (byte) r;
|
||||||
|
this.g = (byte) g;
|
||||||
|
this.b = (byte) b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color fromRgb(int r, int g, int b){
|
||||||
|
return new Color(r + Byte.MIN_VALUE, g + Byte.MIN_VALUE, b + Byte.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color random(Random rand) {
|
||||||
|
return new Color(
|
||||||
|
Utils.randomByte(rand),
|
||||||
|
Utils.randomByte(rand),
|
||||||
|
Utils.randomByte(rand));
|
||||||
|
}
|
||||||
|
|
||||||
|
Color plus(Color other) {
|
||||||
|
return new Color(Utils.bound((short) r + other.r),
|
||||||
|
Utils.bound((short) g + other.g),
|
||||||
|
Utils.bound((short) b + other.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
Color times(float factor) {
|
||||||
|
return new Color((byte) (r * factor),
|
||||||
|
(byte) (g * factor),
|
||||||
|
(byte) (b * factor));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color add(float[] factors, Color[] colors) {
|
||||||
|
float r = 0f;
|
||||||
|
float g = 0f;
|
||||||
|
float b = 0f;
|
||||||
|
for (int i = 0; i < factors.length; i++) {
|
||||||
|
r += factors[i] * colors[i].r;
|
||||||
|
g += factors[i] * colors[i].g;
|
||||||
|
b += factors[i] * colors[i].b;
|
||||||
|
}
|
||||||
|
return new Color(Utils.bound(Math.round(r)),Utils.bound(Math.round(g)), Utils.bound(Math.round(b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color add(Color... colors) {
|
||||||
|
float[] factors = new float[colors.length];
|
||||||
|
for (int i = 0; i < colors.length; i++)
|
||||||
|
factors[i] = 1f;
|
||||||
|
return add(factors, colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color diverge(Random rand) {
|
||||||
|
return new Color(Utils.bound(Utils.div(rand, r)),
|
||||||
|
Utils.div(rand, g),
|
||||||
|
Utils.div(rand, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum() {
|
||||||
|
return r + g + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.awt.Color toColor() {
|
||||||
|
return new java.awt.Color(r - Byte.MIN_VALUE, g - Byte.MIN_VALUE, b - Byte.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(boolean unsigned) {
|
||||||
|
return "(" + (unsigned ? r - Byte.MIN_VALUE : r) + "," + (unsigned ? g - Byte.MIN_VALUE : g) + "," + (unsigned ? b - Byte.MIN_VALUE : b) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
class Generator {
|
||||||
|
|
||||||
|
private final int width;
|
||||||
|
private final int height;
|
||||||
|
private final int width2;
|
||||||
|
private final int height2;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
private float slope;
|
||||||
|
private Color source;
|
||||||
|
private Color divergence;
|
||||||
|
|
||||||
|
private long seed = 0L;
|
||||||
|
|
||||||
|
private Color[][] table;
|
||||||
|
private Random rand;
|
||||||
|
|
||||||
|
Generator(int width, int height) {
|
||||||
|
this(width, height, Utils.randInt(3, 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator(int width, int height, int size) {
|
||||||
|
this(width, height, size, (float) Utils.randInt(40, 60) / 100f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator(int width, int height, int size, float slope) {
|
||||||
|
this(width, height, size, slope, new Color(Utils.randInt(0, 30),
|
||||||
|
Utils.randInt(0, 30),
|
||||||
|
Utils.randInt(0, 30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator(int width, int height, int size, float slope, Color divergence){
|
||||||
|
this(width, height, size, slope, divergence, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator(int width, int height, int size, float slope, Color divergence, Color source) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.size = size;
|
||||||
|
this.width2 = width % size == 0 ? (width / size) : (width / size) + 1;
|
||||||
|
this.height2 = height % size == 0 ? (height / size) : (height / size) + 1;
|
||||||
|
this.slope = slope;
|
||||||
|
this.divergence = divergence;
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color[][] getTable() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth2() {
|
||||||
|
return width2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight2() {
|
||||||
|
return height2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate() {
|
||||||
|
if (seed == 0L)
|
||||||
|
seed = ThreadLocalRandom.current().nextLong();
|
||||||
|
System.out.println("\t\tseed : " + seed);
|
||||||
|
System.out.println("\t\tsize : " + size);
|
||||||
|
System.out.println("\t\tslope : " + slope);
|
||||||
|
System.out.println("\t\tdivergence : " + divergence + " = " + divergence.sum());
|
||||||
|
rand = new Random(seed);
|
||||||
|
table = new Color[width2][height2];
|
||||||
|
table[0][0] = source == null ? Color.random(rand) : source;
|
||||||
|
System.out.println("\t\tsource : " + source);
|
||||||
|
for (int y = 0; y < height2; y++)
|
||||||
|
generateLine(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color getDivergence(int width, int height, int size) {
|
||||||
|
int size2 = (int) Math.min(Math.max(width / size, height / size), Byte.MAX_VALUE * 1.5f);
|
||||||
|
Color c;
|
||||||
|
do {
|
||||||
|
c = new Color(Utils.randInt(0, Byte.MAX_VALUE),
|
||||||
|
Utils.randInt(0, Byte.MAX_VALUE),
|
||||||
|
Utils.randInt(0, Byte.MAX_VALUE));
|
||||||
|
} while (c.sum() * 2 < size2 || c.sum() > Byte.MAX_VALUE * 2);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateLine(int y) {
|
||||||
|
for (int x = 0; x < width2; x++) {
|
||||||
|
Color div = divergence.diverge(rand);
|
||||||
|
if (x > 0 && y == 0) {
|
||||||
|
table[x][y] = Color.add(table[x - 1][y], div);
|
||||||
|
} else if (x == 0 && y > 0) {
|
||||||
|
table[x][y] = Color.add(table[x][y - 1], div);
|
||||||
|
} else if (x > 0 && y > 0) {
|
||||||
|
table[x][y] = Color.add(new float[]{slope, 1f - slope, 1f}, new Color[]{table[x][y - 1], table[x - 1][y], div});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void inspect(int x, int y, int size, boolean unsigned) {
|
||||||
|
|
||||||
|
System.out.println(String.format("Inspect area : %d-%d x %d-%d", x, x + size, y, y + size));
|
||||||
|
|
||||||
|
int sumr = 0;
|
||||||
|
int sumg = 0;
|
||||||
|
int sumb = 0;
|
||||||
|
for (int i = x; i < x + size; i++) {
|
||||||
|
for (int j = y; j < y + size; j++) {
|
||||||
|
System.out.print(String.format("%1$-12s %2$-4d ", table[i][j].toString(unsigned), table[i][j].sum()));
|
||||||
|
sumr += unsigned ? table[i][j].r - Byte.MIN_VALUE : table[i][j].r;
|
||||||
|
sumg += unsigned ? table[i][j].g - Byte.MIN_VALUE : table[i][j].g;
|
||||||
|
sumb += unsigned ? table[i][j].b - Byte.MIN_VALUE : table[i][j].b;
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(String.format("mean : (%d,%d,%d) %d", sumr / (size * size), sumg / (size * size), sumb / (size * size), (sumr + sumg + sumb) / (size * size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void inspectDivergence(int x0, int y0, int size) {
|
||||||
|
System.out.println(String.format("Inspect divergence in area : %d-%d x %d-%d", x0, x0 + size, y0, y0 + size));
|
||||||
|
|
||||||
|
int sumr = 0;
|
||||||
|
int sumg = 0;
|
||||||
|
int sumb = 0;
|
||||||
|
for (int x = x0; x < x0 + size; x++) {
|
||||||
|
for (int y = y0; y < y0 + size; y++) {
|
||||||
|
|
||||||
|
Color div = table[x][y];
|
||||||
|
|
||||||
|
if (x > 0 && y == 0) {
|
||||||
|
div = Color.add(new float[]{1f,-1f},new Color[]{table[x][y], table[x - 1][y]});
|
||||||
|
} else if (x == 0 && y > 0) {
|
||||||
|
div = Color.add(new float[]{1f,-1f},new Color[]{table[x][y], table[x][y-1]});
|
||||||
|
} else if (x > 0 && y > 0) {
|
||||||
|
div = Color.add(new float[]{1f,-slope,slope-1f},new Color[]{table[x][y], table[x][y - 1], table[x - 1][y]});
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print(String.format("%1$-12s %2$-4d ", div, div.sum()));
|
||||||
|
|
||||||
|
sumr += div.r;
|
||||||
|
sumg += div.g;
|
||||||
|
sumb += div.b;
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
System.out.println(String.format("mean : (%d,%d,%d) %d", sumr / (size * size), sumg / (size * size), sumb / (size * size), (sumr + sumg + sumb) / (size * size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] getData() {
|
||||||
|
byte[] data = new byte[width * height * 3];
|
||||||
|
int k = 0;
|
||||||
|
for (int y = 0; y < height2; y++) {
|
||||||
|
for (int x = 0; x < width2; x++) {
|
||||||
|
for (int j = 0; j < Math.min(size, width - x * size); j++) {
|
||||||
|
if (k >= data.length) {
|
||||||
|
System.err.println("\t\toverflow at x:" + x + " y:" + y + " j:" + j + " k:" + k);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
data[k++] = table[x][y].r;
|
||||||
|
data[k++] = table[x][y].g;
|
||||||
|
data[k++] = table[x][y].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Math.min(size, height - y * size) - 1; i++) {
|
||||||
|
Utils.writeArray(data, data, k, k + width * 3, k - width * 3);
|
||||||
|
k += width * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
final class ImageUtils {
|
||||||
|
|
||||||
|
private static final int HEADER_SIZE = 54;
|
||||||
|
|
||||||
|
private ImageUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] generateBmpFile(int width, byte[] data) {
|
||||||
|
int height = data.length / (width * 3);
|
||||||
|
|
||||||
|
data = fixBmpData(data, width, height);
|
||||||
|
|
||||||
|
byte[] output = new byte[HEADER_SIZE + data.length];
|
||||||
|
|
||||||
|
Utils.writeArray(output, getBmpHeader(data.length, width, height), 0);
|
||||||
|
Utils.writeArray(output, data, HEADER_SIZE);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] fixBmpData(byte[] data, int width, int height) {
|
||||||
|
if (data.length > height * width * 3)
|
||||||
|
data = Utils.subArray(data, 0, height * width * 3);
|
||||||
|
|
||||||
|
Utils.translateUnsigned(data);
|
||||||
|
|
||||||
|
int linePadding = (width * 3) % 4;
|
||||||
|
if (linePadding > 0) {
|
||||||
|
byte[] tail = new byte[4-linePadding];
|
||||||
|
tail[tail.length-1] = (byte) 255;
|
||||||
|
data = Utils.interlaceArrays(data, tail, width * 3, height);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] getBmpHeader(int dataSize, int width, int height) {
|
||||||
|
byte[] header = new byte[HEADER_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
Utils.writeArray(header, new byte[]{(int) 66, (int) 77}, 0); // BM
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(dataSize + HEADER_SIZE), 2); // file size
|
||||||
|
//4 bytes application reserved
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(HEADER_SIZE), 10); // offset of data
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(40), 14); // real size of header
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(width), 18); //width
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(height), 22); //height
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(1, 2), 26); //color panes
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(24, 2), 28); //color depth
|
||||||
|
//4 bytes compression method
|
||||||
|
//4 bytes optional image size
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(3780), 38); //horizontal resolution
|
||||||
|
Utils.writeArray(header, Utils.num2bytes(3780), 42); //vertical resolution
|
||||||
|
//4 bytes number of colors
|
||||||
|
//4 bytes number of important colors
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean saveBmpFile(byte[] data, File bmpFile){
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(bmpFile.getPath())) {
|
||||||
|
fos.write(data);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean convertBmpToJpg(File bmpFile, File jpgFile){
|
||||||
|
try {
|
||||||
|
BufferedImage inputImage = ImageIO.read(bmpFile);
|
||||||
|
ImageIO.write(inputImage, "JPG", jpgFile);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
public class LocalTests {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Generator gen = new Generator(800, 800, 2);
|
||||||
|
gen.generate();
|
||||||
|
|
||||||
|
new MarbleViewer(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class MarbleViewer extends JFrame {
|
||||||
|
|
||||||
|
public MarbleViewer(Generator generator){
|
||||||
|
this.setLocation(0,0);
|
||||||
|
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
this.setResizable(false);
|
||||||
|
this.add(new Panel(generator));
|
||||||
|
this.pack();
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Panel extends JPanel{
|
||||||
|
|
||||||
|
private Generator generator;
|
||||||
|
|
||||||
|
Panel(Generator generator){
|
||||||
|
this.generator = generator;
|
||||||
|
Dimension size= new Dimension(generator.getWidth(), generator.getHeight());
|
||||||
|
this.setMinimumSize(size);
|
||||||
|
this.setPreferredSize(size);
|
||||||
|
this.setMaximumSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
int size = generator.getSize();
|
||||||
|
|
||||||
|
for(int x = 0; x < generator.getWidth2(); x++){
|
||||||
|
for(int y = 0; y < generator.getHeight2(); y++){
|
||||||
|
g.setColor(generator.getTable()[x][y].toColor());
|
||||||
|
g.fillRect(x*size, y*size, size, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
final class Utils {
|
||||||
|
|
||||||
|
private Utils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte utils
|
||||||
|
*/
|
||||||
|
|
||||||
|
static byte randomByte(Random rand) {
|
||||||
|
return (byte) (rand.nextInt(Byte.MAX_VALUE - Byte.MIN_VALUE) + Byte.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte bound(int value) {
|
||||||
|
if (value > Byte.MAX_VALUE)
|
||||||
|
return Byte.MAX_VALUE;
|
||||||
|
if (value < Byte.MIN_VALUE)
|
||||||
|
return Byte.MIN_VALUE;
|
||||||
|
return (byte) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte array utils
|
||||||
|
*/
|
||||||
|
|
||||||
|
static byte[] subArray(byte[] array, int start, int stop) {
|
||||||
|
byte[] out = new byte[stop - start];
|
||||||
|
for (int i = start; i < stop; i++) {
|
||||||
|
out[i - start] = array[i];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void translateUnsigned(byte[] data){
|
||||||
|
for(int i = 0; i < data.length; i++){
|
||||||
|
data[i] = (byte) (data[i] - Byte.MIN_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] interlaceArrays(byte[] data, byte[] added, int size, int times){
|
||||||
|
byte[] out = new byte[data.length + added.length*times];
|
||||||
|
int size2 = size+added.length;
|
||||||
|
for(int i = 0; i < times; i++){
|
||||||
|
writeArray(out, data, size2*i, size2*i+size, size*i);
|
||||||
|
writeArray(out, added, size2*i+size, size2*(i+1), 0);
|
||||||
|
}
|
||||||
|
writeArray(out, data, size2*times, out.length-size2*times, size*times);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeArray(byte[] out, byte[] data, int start, int stop, int padding){
|
||||||
|
for(int i = 0; i < Math.min(stop, out.length)-start; i++){
|
||||||
|
out[i+start] = data[i+padding];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeArray(byte[] out, byte[] data, int start, int padding){
|
||||||
|
writeArray(out, data, start, start+data.length-padding, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeArray(byte[] out, byte[] data, int start){
|
||||||
|
writeArray(out, data, start, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] num2bytes(int number, int nbyte){
|
||||||
|
byte[] b = new byte[nbyte];
|
||||||
|
for(int i = 0; i < nbyte; i++){
|
||||||
|
b[i] = (byte)(number%256);
|
||||||
|
number = number/256;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] num2bytes(int number){
|
||||||
|
return num2bytes(number, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int randInt(int min, int max){
|
||||||
|
return ThreadLocalRandom.current().nextInt(max-min)+min;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int div(Random rand, byte src){
|
||||||
|
return Math.round(rand.nextFloat()*2*src-src);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
class WallpaperGenerator {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
String file = "wallpaper";
|
||||||
|
Dimension screen = getScreenSizes();
|
||||||
|
int width = screen.width;
|
||||||
|
int height = screen.height;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
if (args.length > 0) {
|
||||||
|
file = args[0];
|
||||||
|
}
|
||||||
|
if (args.length > 1) {
|
||||||
|
width = Integer.parseInt(args[1]);
|
||||||
|
height = Integer.parseInt(args[1]);
|
||||||
|
}
|
||||||
|
if (args.length > 2) {
|
||||||
|
height = Integer.parseInt(args[2]);
|
||||||
|
}
|
||||||
|
if (args.length > 3) {
|
||||||
|
size = Integer.parseInt(args[3]);
|
||||||
|
}
|
||||||
|
makeWallpaper(file, width, height, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dimension getScreenSizes() {
|
||||||
|
Dimension dim = new Dimension(0, 0);
|
||||||
|
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
|
||||||
|
dim.width = Math.max(dim.width, gd.getDisplayMode().getWidth());
|
||||||
|
dim.height = Math.max(dim.height, gd.getDisplayMode().getHeight());
|
||||||
|
}
|
||||||
|
return dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeWallpaper(String name, int width, int height, int size) {
|
||||||
|
System.out.println("Making wallpaper '" + name + "' " + width + "x" + height + "px");
|
||||||
|
|
||||||
|
File bmpFile = new File(name + ".bmp");
|
||||||
|
File outputFile = new File(name + ".jpg");
|
||||||
|
|
||||||
|
long t0 = System.currentTimeMillis();
|
||||||
|
Generator gen = size == 0 ? new Generator(width, height) : new Generator(width, height, size);
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
gen.generate();
|
||||||
|
System.out.println("\tGeneration done in " + (System.currentTimeMillis() - t1) + " ms");
|
||||||
|
|
||||||
|
t1 = System.currentTimeMillis();
|
||||||
|
byte[] file = ImageUtils.generateBmpFile(width, gen.getData());
|
||||||
|
System.out.println("\t\t" + file.length + " bytes");
|
||||||
|
System.out.println("\tData writing done in " + (System.currentTimeMillis() - t1) + " ms");
|
||||||
|
|
||||||
|
t1 = System.currentTimeMillis();
|
||||||
|
if(!ImageUtils.saveBmpFile(file, bmpFile))
|
||||||
|
return;
|
||||||
|
System.out.println("\tFile writing done in " + (System.currentTimeMillis() - t1) + " ms");
|
||||||
|
|
||||||
|
t1 = System.currentTimeMillis();
|
||||||
|
if(!ImageUtils.convertBmpToJpg(bmpFile, outputFile))
|
||||||
|
return;
|
||||||
|
System.out.println("\tFile converting done in " + (System.currentTimeMillis() - t1) + " ms");
|
||||||
|
|
||||||
|
if (bmpFile.delete())
|
||||||
|
System.out.println("\tFile '" + bmpFile.getName() + "' deleted");
|
||||||
|
|
||||||
|
System.out.println("Wallpaper done in " + (System.currentTimeMillis() - t0) + " ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package fr.klemek.marble;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class UtilsTest {
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void bound() {
|
||||||
|
assertEquals((byte)-128, Utils.bound(-200));
|
||||||
|
assertEquals((byte)-128, Utils.bound(-129));
|
||||||
|
assertEquals((byte)-128, Utils.bound(-128));
|
||||||
|
assertEquals((byte)-64, Utils.bound(-64));
|
||||||
|
assertEquals((byte)0, Utils.bound(0));
|
||||||
|
assertEquals((byte)64, Utils.bound(64));
|
||||||
|
assertEquals((byte)127, Utils.bound(127));
|
||||||
|
assertEquals((byte)127, Utils.bound(128));
|
||||||
|
assertEquals((byte)127, Utils.bound(200));
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void subArray() {
|
||||||
|
byte[] array0 = new byte[]{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
assertArrayEquals(new byte[]{2,3,4}, Utils.subArray(array0, 2, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void translateUnsigned() {
|
||||||
|
byte[] array0 = new byte[]{-128,-64,0,64,127};
|
||||||
|
Utils.translateUnsigned(array0);
|
||||||
|
assertArrayEquals(new byte[]{0,64,(byte)128,(byte)192,(byte)255}, array0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void interlaceArrays() {
|
||||||
|
byte[] array0 = new byte[10];
|
||||||
|
byte[] array1 = new byte[]{1,1};
|
||||||
|
assertArrayEquals(new byte[]{0,0,0,1,1,0,0,0,1,1,0,0,0,0}, Utils.interlaceArrays(array0, array1, 3,2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void writeArray() {
|
||||||
|
byte[] array0 = new byte[10];
|
||||||
|
byte[] array1 = new byte[]{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
Utils.writeArray(array0,array1,2,5,3);
|
||||||
|
assertArrayEquals(new byte[]{0,0,3,4,5,0,0,0,0,0}, array0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void writeArray1() {
|
||||||
|
byte[] array0 = new byte[10];
|
||||||
|
byte[] array1 = new byte[]{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
Utils.writeArray(array0,array1,2,3);
|
||||||
|
assertArrayEquals(new byte[]{0,0,3,4,5,6,7,8,9,0}, array0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void writeArray2() {
|
||||||
|
byte[] array0 = new byte[10];
|
||||||
|
byte[] array1 = new byte[]{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
Utils.writeArray(array0,array1,2);
|
||||||
|
assertArrayEquals(new byte[]{0,0,0,1,2,3,4,5,6,7}, array0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void num2bytes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void num2bytes1() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user