-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathFloodFillTest.java
127 lines (117 loc) · 4.84 KB
/
FloodFillTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import org.junit.Test;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.zip.CRC32;
import static org.junit.Assert.assertEquals;
import javax.swing.JFrame;
import javax.swing.JPanel;
// Ensure that the floating point arithmetic works the same in all environments.
// We finally get to use this rarest of the rare Java keywords.
public strictfp class FloodFillTest {
private static final Color[] colors = {
Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA
};
private static Color createRandomColour(Random rng) {
// Create a random peppy colour in HSB space.
float hue = (float)(rng.nextDouble());
float saturation = (float)(rng.nextDouble() * 0.1 + 0.9);
// Avoid creating pure white used here as background colour.
float brightness = (float)(rng.nextDouble() * 0.3 + 0.69);
return new Color(Color.HSBtoRGB(hue, saturation, brightness));
}
// For the main method, create some fancier curves.
private static strictfp BufferedImage createRandomCurves(int w, int h, int lines, Random rng) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.setColor(Color.WHITE);
g2.fill(new Rectangle2D.Double(0, 0, w, h));
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(3.0f));
g2.drawLine(0, 0, w-1, 0);
g2.drawLine(0, 0, 0, h-1);
g2.drawLine(w-1, 0, w-1, h-1);
g2.drawLine(0, h-1, w-1, h-1);
for(int i = 0; i < lines; i++) {
int width = rng.nextInt(w/2) + w/8;
int height = rng.nextInt(h/2) + h/8;
int x = rng.nextInt(w) - w/4;
int y = rng.nextInt(h) - h/4;
double start = rng.nextInt(360);
double extent = 180 + rng.nextInt(180);
g2.draw(new Arc2D.Double(x, y, width, height, start, extent, Arc2D.OPEN));
}
return img;
}
private static class ImagePanel extends JPanel {
private final Image img;
public ImagePanel(Image img, String toolTip) {
this.img = img;
this.setToolTipText(toolTip);
this.setPreferredSize(new Dimension(img.getWidth(this), img.getHeight(this)));
//this.setBorder(BorderFactory.createEtchedBorder());
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, this);
}
}
@Test public void testFloodFill() {
Random rng = new Random(4321);
CRC32 check = new CRC32();
int stillWhite = Color.WHITE.getRGB();
for(int i = 0; i < 30; i++) {
// Create a new random image to flood fill.
int w = 50 + rng.nextInt(30 * i + 1);
int h = 50 + rng.nextInt(30 * i + 1);
int lines = 3 * i;
BufferedImage img = createRandomCurves(w, h, lines, rng);
// Flood fill all the white nooks of current image
int colIdx = 0;
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
if(img.getRGB(x, y) == stillWhite) {
FloodFill.floodFill(img, x, y, colors[colIdx]);
colIdx = (colIdx + 1) % colors.length;
}
}
}
// Update the checksum from every pixel of the resulting image.
for(int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
check.update(img.getRGB(x, y));
}
}
}
assertEquals(2800237690L, check.getValue());
}
public static void main(String[] args) {
Random rng = new Random(5555);
final int WIDTH = 500, HEIGHT = 600;
BufferedImage original = createRandomCurves(WIDTH, HEIGHT, 16, rng);
BufferedImage floodFilled = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
floodFilled.getGraphics().drawImage(original, 0, 0, new JPanel());
for(int y = 0; y < HEIGHT; y++) {
for(int x = 0; x < WIDTH; x++) {
if(floodFilled.getRGB(x, y) == Color.WHITE.getRGB()) {
Color col = createRandomColour(rng);
FloodFill.floodFill(floodFilled, x, y, col);
}
}
}
JFrame f = new JFrame("Flood Fill Demo");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLayout(new FlowLayout());
f.add(new ImagePanel(original, "Random lines"));
f.add(new ImagePanel(floodFilled, "Flood Fill"));
f.pack();
f.setVisible(true);
}
}