I wrote a flood fill algorithm in Java to get the bounds of each sprite in a spritesheet. The problem is that it works fine with some sprites but with the rest of them it doesn't. For example:
https://i.gyazo.com/cdbdb0ce40a46445ca8e7b62176ab442.png
I put a red square surrounding some of the errors.
This is the flood fill method:
private static Rectangle floodFill(int[] pixels, int x0, int y0, int width, int height) {
Rectangle frame = new Rectangle(x0,y0,1,1);
Deque<Point> queue = new LinkedList<>();
queue.addLast(new Point(x0,y0));
while(!queue.isEmpty()) {
Point p = queue.poll();
final int x = p.x;
final int y = p.y;
if(x < 0 || x >= width || y < 0 || y >= height) {
continue;
}
// Is not part of a sprite, or has been visited before
if(pixels[x+y*width] == 0) {
continue;
}
pixels[x+y*width] = 0; // Mark as visited
// Update bounds
if(x < frame.x) {
frame.x = x;
} else if(x > frame.x + frame.width) {
frame.width++;
}
if(y < frame.y) {
frame.y = y;
} else if(y > frame.y + frame.height) {
frame.height++;
}
queue.add(new Point(x-1,y));
queue.add(new Point(x-1,y-1));
queue.add(new Point(x-1,y+1));
queue.add(new Point(x+1,y));
queue.add(new Point(x+1,y-1));
queue.add(new Point(x+1,y+1));
queue.add(new Point(x,y-1));
queue.add(new Point(x,y+1));
}
return frame;
}
The flood fill method is called from here:
private static List<Rectangle> split(BufferedImage image) {
List<Rectangle> sprites = new ArrayList<>();
int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData().clone();
final int width = image.getWidth();
final int height = image.getHeight();
for(int y = 0;y < height;y++) {
for(int x = 0;x < width;x++) {
if(pixels[x+y*width] != 0) {
Rectangle r = floodFill(pixels,x,y,width,height);
sprites.add(r);
}
}
}
return sprites;
}
What it does is visit each pixel, and if it is not equal to zero (background color), then it is a sprite, and the flood fill method gets it bounds.
I have searched for a solution and I've tried many times with different implementations but I couldn't found a solution.
Can someone help me? I think I am missing something but I can't see it.
Thanks!