I need to write a flood fill algorithm to color pixels of an image which are inside black borders. I've wrote the following based on some posts here on SO:
private Queue<Point> queue = new LinkedList<Point>();
private int pickedColorInt = 0;
private void floodFill(Pixmap pixmap, int x, int y){
//set to true for fields that have been checked
boolean[][] painted = new boolean[pixmap.getWidth()][pixmap.getHeight()];
//skip black pixels when coloring
int blackColor = Color.rgba8888(Color.BLACK);
queue.clear();
queue.add(new Point(x, y));
while(!queue.isEmpty()){
Point temp = queue.remove();
int temp_x = temp.getX();
int temp_y = temp.getY();
//only do stuff if point is within pixmap's bounds
if(temp_x >= 0 && temp_x < pixmap.getWidth() && temp_y >= 0 && temp_y < pixmap.getHeight()) {
//color of current point
int pixel = pixmap.getPixel(temp_x, temp_y);
if (!painted[temp_x][temp_y] && pixel != blackColor) {
painted[temp_x][temp_y] = true;
pixmap.drawPixel(temp_x, temp_y, pickedColorInt);
queue.add(new Point(temp_x + 1, temp_y));
queue.add(new Point(temp_x - 1, temp_y));
queue.add(new Point(temp_x, temp_y + 1));
queue.add(new Point(temp_x, temp_y - 1));
}
}
}
}
This doesn't work as expected. For example, on following test image:
Random rectangles will get recolored depending of where I've clicked. For example, clicking anywhere below purple rectangle will recolor purple rectangle. Clicking inside purple rectangle recolors the green rectangle. I've checked it and I'm passing right parameters to method so the issue is probably somewhere inside my loop.
Flood fill algorithm can be simply modeled as graph traversal problem, representing the given area as a matrix and considering every cell of that matrix as a vertex that is connected to points above it, below it, to right of it, and to left of it and in case of 8-connections, to the points at both diagonals also.
Disadvantage: Very slow algorithm. May be fail for large polygons. Initial pixel required more knowledge about surrounding pixels.
Boundary-fill algorithm is faster than the Flood-fill algorithm. In Flood-fill algorithm a random colour can be used to paint the interior portion then the old one is replaced with a new one. In Boundary-fill algorithm Interior points are painted by continuously searching for the boundary colour.
Flood fill is an algorithm mainly used to determine a bounded area connected to a given node in a multi-dimensional array. It is a close resemblance to the bucket tool in paint programs.
Your algorithm is correct, only your input parameters are not.
Random rectangles will get recolored depending of where I've clicked. For example, clicking anywhere below purple rectangle will recolor purple rectangle. Clicking inside purple rectangle recolors the green rectangle.
If you look at the picture, the colored rectangles are not really random. The real problem is an incorrect Y-coordinate. Specifically your Y-coordinate is inverted.
That's because most of the time LibGDX uses a lower-left, y-up coordinate system, but in case of Pixmap
it is top-left y-down.
A simple fix for this is to just invert the Y-value by doing y = pixmap.getHeight() - y
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With