Android在画布上撤消绘图方法

时间:2016-07-06 00:28:42

标签: android canvas bitmap

我创建了一些拍照并显示图片的代码,然后用户可以在图片上绘图。

我想实现undo方法。我的代码基于我读过的很多例子。问题出在我的onDraw方法中 - 示例不使用drawBitmap但对我来说,我必须在画布上绘制位图才能显示图像。

显示的代码显示图像,允许在图像上绘图,但不撤消图纸。我无法弄清楚错误/如何修复它。

public class PhotoView extends View {

    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    private ArrayList<Path> paths = new ArrayList<>();

    public PhotoView(Context c) {
        super(c);
        mBitmap = mutableBitmap;
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //canvas.drawColor(0xFFAAAAAA);
        ****must call in order for image to show up *****
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        //canvas.drawPath(mPath, mPaint);
        for (Path p : paths){
            canvas.drawPath(p, mPaint);
        }
        canvas.drawPath(mPath, mPaint); //real time drawing on canvas
    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touchStart(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touchMove(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    private void touchUp() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        paths.add(mPath);
        mPath = new Path();
        //mPath.reset();
        //paths.add(mPath);
    }

    public void onClickUndo () {
        if (paths.size()>0)
        {
            paths.remove(paths.size()-1);
            invalidate();
        }
    }
    public Bitmap getPic() {
        mCanvas.save();
        return mBitmap;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchStart(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touchUp();
                invalidate();
                break;
        }
        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

因此,当涉及到用户绘制的Paths时,您正在做两件事。

  1. 方法touchUp()mCanvas.drawPath(mPath, mPaint);
  2. onDraw()canvas.drawPath(p, mPaint);
  3. 当您致电onClickUndo()时,onDraw()内容将被取消。但touchUp()中的那个未被撤消。这就是你的撤销似乎不起作用的原因。问题在第mCanvas.drawPath(mPath, mPaint);

    <强>解决方案
    不要在mPath上绘制mCanvas。执行此操作后,您的mBitmap会发生变化(您正在paths上绘制mBitmap。没有办法撤消这个。这不是你想要的。如果您想在paths中使用mBitmap,以便将其保存在文件中,请最后执行此操作(可能有save()之类的方法,并在该方法中执行此操作)