final Point p1 = new Point();
p1.x=(int) x; //x co-ordinate where the user touches on the screen
p1.y=(int) y; //y co-ordinate where the user touches on the screen
new TheTask(yourbitmap, p1, sourceColor,targetColor).execute();// use asyntask for efficiency
class TheTask extends AsyncTask<Void, Integer, Void> {
Bitmap bmp;
Point pt;
int replacementColor,targetColor;
ProgressDialog pd;
public TheTask(Bitmap bm,Point p, int sc, int tc)
{
this.bmp=bm;
this.pt=p;
this.replacementColor=tc;
this.targetColor=sc;
pd= new ProgressDialog(context);
pd.setMessage("Filling....");
}
@Override
protected void onPreExecute() {
pd.show();
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected Void doInBackground(Void... params) {
FloodFill f= new FloodFill();
f.floodFill(bmp,pt,targetColor,replacementColor);
return null;
}
@Override
protected void onPostExecute(Void result) {
pd.dismiss();
invalidate();
}
Finally use a FloodFill algorithm to fill a closed area
public class FloodFill {
public void floodFill(Bitmap image, Point node, int targetColor,
int replacementColor) {
int width = image.getWidth();
int height = image.getHeight();
int target = targetColor;
int replacement = replacementColor;
if (target != replacement) {
Queue<Point> queue = new LinkedList<Point>();
do {
int x = node.x;
int y = node.y;
while (x > 0 && image.getPixel(x - 1, y) == target) {
x--;
}
boolean spanUp = false;
boolean spanDown = false;
while (x < width && image.getPixel(x, y) == target) {
image.setPixel(x, y, replacement);
if (!spanUp && y > 0 && image.getPixel(x, y - 1) == target) {
queue.add(new Point(x, y - 1));
spanUp = true;
} else if (spanUp && y > 0
&& image.getPixel(x, y - 1) != target) {
spanUp = false;
}
if (!spanDown && y < height - 1
&& image.getPixel(x, y + 1) == target) {
queue.add(new Point(x, y + 1));
spanDown = true;
} else if (spanDown && y < height - 1
&& image.getPixel(x, y + 1) != target) {
spanDown = false;
}
x++;
}
} while ((node = queue.poll()) != null);
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…