Reputation: 3099
I am writing an application that implements Flood Fill 4 algorithm. It works perfectly fine as long as the borders are thick. The algorithm fills in a certain color within the boarder. I tried to make the boarder thinner, but in that case the pixels were able to went out the boarder, and the program crashed.
Flood fill algorithm works EXCELLENT within the "thick boarder" area, which is the right triangle. However, the algorithm does not work within the other four areas because the boarders are thin, i.e. leakage takes place. Except for making the other boarders thick, are there any methods I can use?
Here is the complete code, it is just one class:
import java.awt.Color;
import java.awt.Container;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MyPolygon extends JFrame {
private JLabel my;
private BufferedImage buffered;
public MyPolygon() throws InterruptedException {
createMy();
}
private void createMy() throws InterruptedException {
Container contentPane = getContentPane();
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
contentPane.setSize(1200, 900);
my = new JLabel();
my.setIcon(new ImageIcon("myImage.png"));
my.setBounds(10,200, 1000, 800);
contentPane.add(my);
setSize(1200, 900);
setVisible(true);
setLocationRelativeTo(null);
Image img = ((ImageIcon) my.getIcon()).getImage();
buffered = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
buffered.getGraphics().drawImage(img, 0, 0, null);
int fill = 100;
boundaryFill4(200, 215, fill, 50);
my.setIcon(new ImageIcon(buffered));
}
// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
Color c = new Color(buffered.getRGB(x, y));
int current = c.getRed();
System.out.println(x + " " + y + " | " + current);
if ((current > boundary) && (current != fill)) {
int red = fill;
int green = fill;
int blue = fill;
c = new Color(red, green, blue);
buffered.setRGB(x, y, c.getRGB());
boundaryFill4(x + 1, y, fill, boundary);
boundaryFill4(x - 1, y, fill, boundary);
boundaryFill4(x, y + 1, fill, boundary);
boundaryFill4(x, y - 1, fill, boundary);
}
}
// Main method
public static void main(String args[]) throws InterruptedException {
MyPolygon my = new MyPolygon();
my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Upvotes: 0
Views: 1055
Reputation: 12985
Your if
needs some work and you have no end condition on the recursion except for the colors.
1
The function boundaryFill4
needs to look for x and y being small (top or left edge of picture) or large (bottom or top edge). It will look like this:
if (x < 0 || x > 200 || y < 0 || y > 200) {
return;
}
2
If you look closely at the image, you can see that the edges of the border line (particularly when thin) uses faded pixels to keep the line from looking too jaggy. It's a smoothing technique.
One debugging tip is to add a short time delay to the top of the boundaryFill4
function so you can see the process happening. It should show you where the fill is escaping and you can look at that spot blown up to get more clues.
The test currently looks for a pixel that has more RED in it than level 50 but isn't the same RED as the fill color.
The white in the center probably has all three RGB levels at the full value.
The border has pixels with all three RGB colors seemingly near 0 but the smoothing technique causes it to put higher values of RGB in some pixels to hide the jaggies. Be sure to check what colors levels the border actually is when its thin. Maybe the center pixels of the line are brighter than you think.
The fill color is a sort of dark grey.
Here are some ideas:
Upvotes: 1