I'm designing a finger paint app and I've implemented a Floodfill algorithm for filling enclosed areas. It works great. Occasionally however, the entire bitmap turns transparent (getpixel returns 0). It's difficult to reproduce the problem. I have to rapidly fill many areas for the error to occur. The entire screen goes black when this happens.
I've worked around this by retrieving the last image the user saw (effectively performing an "undo" operation). I have no idea why this happens. Here's the floodfill algorithm:
protected Void doInBackground(Object... params) {
Bitmap bmp = (Bitmap) params[0];
Point pt = (Point) params[1];
int targetColor = (Integer) params[2];
int replacementColor = (Integer) params[3];
if (bmp.getPixel(pt.x, pt.y) == replacementColor)
return null;
Queue<Point> q = new LinkedList<Point>();
q.add(pt);
while (q.size() > 0) {
Point n = q.poll();
if (bmp.getPixel(n.x, n.y) != targetColor) {
continue;
}
Point w = n, e = new Point(n.x + 1, n.y);
while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) {
bmp.setPixel(w.x, w.y, replacementColor);
if ((w.y > 0)
&& (bmp.getPixel(w.x, w.y - 1) == targetColor))
q.add(new Point(w.x, w.y - 1));
if ((w.y < bmp.getHeight() - 1)
&& (bmp.getPixel(w.x, w.y + 1) == targetColor))
q.add(new Point(w.x, w.y + 1));
w.x--;
}
while ((e.x < bmp.getWidth() - 1)
&& (bmp.getPixel(e.x, e.y) == targetColor)) {
bmp.setPixel(e.x, e.y, replacementColor);
if ((e.y > 0)
&& (bmp.getPixel(e.x, e.y - 1) == targetColor))
q.add(new Point(e.x, e.y - 1));
if ((e.y < bmp.getHeight() - 1)
&& (bmp.getPixel(e.x, e.y + 1) == targetColor))
q.add(new Point(e.x, e.y + 1));
e.x++;
}
}
return null;
}
My workaround does a pretty good job and displays a message saying an error has occurred and has recovered. But does anyone else know why this happens?
Got it - I have to disable everything while the floodfill algorithm is active - including other floodfills running at the same time. Otherwise they all operate on the same bitmap at the same time and things get very hairy..