采用的android洪水填充算法走出内存异常 [英] android using flood fill algorithm getting out of memory exception

查看:167
本文介绍了采用的android洪水填充算法走出内存异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在你的建议,我得到了工作code:

after your suggestions i got working code:

public class FingerPaint extends Activity {

private RelativeLayout drawingLayout;
private MyView myView;
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    myView = new MyView(this);
    setContentView(myView);
    drawingLayout.addView(myView);
}

public class MyView extends View {

    private Paint paint;
    private Path path;
    Bitmap mBitmap;
    ProgressDialog pd;
    final Point p1 = new Point();
    Canvas canvas;
    //Bitmap mutableBitmap ;
    public MyView(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.paint).copy(Bitmap.Config.ARGB_8888, true);


        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:

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

// flood fill

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

现在,它正在fine.ThanQ

Now it is working fine.ThanQ

推荐答案

使用异步任务。运行在主UI线程每一个操作可能导致的内存溢出异常。我的建议,使用线程。难道此时,floodFill背景。检查此链接。可以帮助你。 <一href="http://stackoverflow.com/questions/8723590/fill-the-complete-canvas-but-keep-the-bound-fill-area-as-it-is-like-circle-rect/12777805#12777805">Fill完整的画布,但保留约束填充区域,因为它是像圆,矩形

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

使用此时,floodFill了。

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

编辑:

其中的一个用户评论说,解决方案@ Android的洪水填充算法的作品比快这里的解决方案张贴。因此,需要看看在链接的解决方案,虽然我没有测试它自己。

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.

这篇关于采用的android洪水填充算法走出内存异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆