Android绘图填充工具

时间:2014-07-16 17:20:12

标签: android android-canvas android-view

我正在为Android制作一个绘图应用程序,我需要一些帮助添加填充工具。

我希望该工具能够填充填充,并且在Microsoft Paint中表现得像在手机上一样。

我有一个在画布上绘制路径的自定义视图。我为不同的笔和画笔绘制了不同的路径,我允许用户选择线条粗细和颜色。

当我这样做时:

paint.setStyle(Paint.Style.FILL);

而且我画画,我没有得到我想要的填充。

我已经获得了一些使用“Flood Fill Algorithm”的建议,但我无法弄清楚如何在我的代码中实现它。

我在哪里可以看到我想要做的一个例子?有没有人有示例代码向我展示如何使用我的android视图使该工具工作?

修改

CartoonView.java:

    public class CartoonView extends View {
        ArrayList<Paint> paints = new ArrayList<Paint>();
        ArrayList<Path> paths = new ArrayList<Path>();
        int color;
        int thickness;
        boolean pencilSelected;

    public boolean isPencilSelected() {
        return pencilSelected;
    }

    public void setPencilSelected(boolean pencilSelected) {
        this.pencilSelected = pencilSelected;
    }

    public ArrayList<Paint> getPaints() {
        return paints;
    }

    public void setPaints(ArrayList<Paint> paints) {
        this.paints = paints;
    }

    public ArrayList<Path> getPaths() {
        return paths;
    }

    public void setPaths(ArrayList<Path> paths) {
        this.paths = paths;
    }

    public int getThickness() {
        return thickness;
    }

    public int getColor() {
        return color;
    }

    public CartoonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        color = Color.BLACK;
        thickness = 3;
        pencilSelected = true;
        createPaint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (Path path : paths) {
            canvas.drawPath(path, paints.get(paths.indexOf(path)));
        }
    }

    public void setPaintColor(int newColor) {
        color = newColor;
        createPaint();
    }

    public void setPaintThickness(int newThickness) {
        thickness = newThickness;
        createPaint();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.isEnabled()) {
            Path path;
            if (paths.size() == 0) {
                path = new Path();

                Paint paint = new Paint();
                paint.setAntiAlias(true);
                paint.setStrokeWidth(5f);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeJoin(Paint.Join.ROUND);
                paint.setColor(color);
                paint.setStrokeWidth(thickness);

                thickness = (int) paint.getStrokeWidth();

                paths.add(path);
                paints.add(paint);
            } else {
                path = paths.get(paths.size() - 1);
            }
            float eventX = event.getX();
            float eventY = event.getY();
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(eventX, eventY);
                return true;
            case MotionEvent.ACTION_MOVE:
                path.lineTo(eventX, eventY);
                break;
            default:
                return true;
            }
            invalidate();
        }
        return true;
    }

    public void createPaint() {
        Path path = new Path();

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(5f);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setColor(color);
        paint.setStrokeWidth(thickness);

        paths.add(path);
        paints.add(paint);
    }

    public void clearView(){
        paths.clear();
        paints.clear();
        invalidate();
    }
}

2 个答案:

答案 0 :(得分:3)

我完全同意那些评论洪水填充算法的评论员。

以下是您想要的功能。试试吧:

private void FloodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor){
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++;
    }
}}

您还可以在链接上阅读有关Flood填充的一些信息:Link1Link2Link3

希望你能回答你的问题。请让我知道我可以用其他方式帮助你,或者你对上述答案有疑问。

享受编码......:)

更新了更多信息:

上面的functiona将在FloodFill算法的基础上工作。它究竟会做什么, 它会在您触摸时检测该像素上的像素点和颜色。 然后它会按照所选颜色按像素到像素填充颜色,直到任何像素都没有与当前颜色不同的颜色。

我希望它会对你有所帮助。

答案 1 :(得分:0)

private void setupDrawing(){

        drawPath = new Path();
        drawPaint = new Paint();
        drawPaint.setColor(paintColor);
        drawPaint.setAntiAlias(true);
        drawPaint.setStrokeWidth(50);
        drawPaint.setStyle(Paint.Style.STROKE);

     // here i use round round u may use anther option also :) 

        drawPaint.setStrokeJoin(Paint.Join.ROUND);
        drawPaint.setStrokeCap(Paint.Cap.ROUND);
        canvasPaint = new Paint(Paint.DITHER_FLAG);
 }