android using flood fill algorithm getting out of memory exception

倾然丶 夕夏残阳落幕 提交于 2019-11-29 08:57:36
Raghunandan

Use Async Task. Running every operation on Main Ui thread may cause's out of memory exception. My suggestion , use threads. Do Floodfill in background. Check this link. May help You. Fill the complete canvas but keep the bound fill area as it is like circle, rectangle

    private Paint paint;
private Path path;
Bitmap mBitmap;
ProgressDialog pd;
 final Point p1 = new Point();
Canvas canvas;
private static final float TOUCH_TOLERANCE = 4;
float mX,mY;

public DrawingView(Context context ) {
    super(context);

    this.paint = new Paint();
    this.paint.setAntiAlias(true);
    pd= new ProgressDialog(context);
    this.paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeWidth(5f);
    mBitmap= BitmapFactory.decodeResource(getResources(), R.drawable.rose_sketch);
    this.path = new Path();
}

@Override
protected void onDraw(Canvas canvas) {
    this.canvas=canvas;
    this.paint.setColor(Color.GREEN);
    canvas.drawBitmap(mBitmap, 0, 0,paint);

}

@Override
public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();
    float y = event.getY();
    switch(event.getAction())
    {
    case MotionEvent.ACTION_DOWN:
    //final Point p1 = new Point();
    p1.x=(int) x;
    p1.y=(int) y;
    final int sourceColor=  mBitmap.getPixel((int)x,(int) y);
    final int targetColor = paint.getColor();
    new TheTask(mBitmap, p1, sourceColor, targetColor).execute();
    invalidate();    
    }
    return true;
}

public void clear() {
    path.reset();
    invalidate();
}
public int getCurrentPaintColor() {
    return paint.getColor();
}
class TheTask extends AsyncTask<Void, Integer, Void> {

    Bitmap bmp;
    Point pt;
    int replacementColor,targetColor;

    public TheTask(Bitmap bm,Point p, int sc, int tc)
    {
        this.bmp=bm;
        this.pt=p;
        this.replacementColor=tc;
        this.targetColor=sc;
        pd.setMessage("Filling....");
        pd.show();
    }
    @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();
    }
}
}

USE FLOODFILL NOW.

 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);
    }
}
}

Edit:

One of the users commented that the solution @ Android flood-fill algorithm works faster than the solution posted here. So take look at the solution in the link although i haven't tested it myself.

I have seen this problem with my code whenver there is some really complex computations going on in the UI thread. If you have implemented flood fill in the UI thread, the computations are causing 99% CPU usage due to which other applications and services are not getting thier share of the CPU. As a result, android will try to kill your app inorder to restore the integrity of the System. As a simple solution, try to offload your computations to a AsyncTask or a thread.

I think you have to swich off the multitoutch of your screen because of that it went to out of memory....

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!