Android Canvas Undo and Redo with Bitmap



我在画布上的撤消和重做操作时遇到问题。我注意到如果我不在 Ondraw() 方法中使用 canvas.drawbitmap,下面的代码可以工作,但我需要绘制到位图,以便我可以保存画布图像并加载图像。请帮助我。下面是我的代码。

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.akinslove.drawingapp.activities.DrawingCanvasActivity;
public class DrawView extends View {
    // for bitmap
    private Bitmap mainBitmap;
    private Canvas mainCanvas;
    private Paint mainbitmapPaint;
    // for canvas
    private Path currentPath;
    private Paint currentpathPaint;

    private ArrayList<Path> paths = new ArrayList<Path>();
    private ArrayList<Path> undonePaths = new ArrayList<Path>(); 
    public DrawView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialiseMyComponents();
    }
    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialiseMyComponents();
    }
    public DrawView(Context context) {
        super(context);
        initialiseMyComponents();
    }
    private void initialiseMyComponents() {
        currentPath = new Path();
        currentpathPaint = new Paint();
        currentpathPaint.setColor(Color.BLACK);
        currentpathPaint.setStrokeWidth(10);
        currentpathPaint.setStyle(Style.STROKE);
        currentpathPaint.setStrokeJoin(Join.ROUND);
        currentpathPaint.setStrokeCap(Cap.ROUND);
        currentpathPaint.setAntiAlias(true);
        mainbitmapPaint = new Paint();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        for (Path p : paths){
            canvas.drawPath(p, currentpathPaint);
        }
        canvas.drawPath(currentPath, currentpathPaint);
            **//I wish to use the below line of code
            canvas.drawBitmap(mainBitmap, 0, 0, mainbitmapPaint);**
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (mainBitmap == null) {
            mainBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
            mainCanvas = new Canvas(mainBitmap);
            mainCanvas.drawColor(Color.WHITE);
        }
    }
    float lastX;
    float lastY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        float x = event.getX();
        float y = event.getY();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            undonePaths.clear();

            DrawingCanvasActivity.IMAGEDRAWN = true;
            currentPath.moveTo(x, y);
            lastX = x;
            lastY = y;
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            currentPath.quadTo(lastX, lastY, (lastX + x) / 2, (lastY + y) / 2);
            mainCanvas.drawPath(currentPath, currentpathPaint);
            lastX = x;
            lastY = y;
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            currentPath.lineTo(x, y);
            mainCanvas.drawPath(currentPath, currentpathPaint);
                    // kill this so we don't double draw
                    paths.add(currentPath);
                    currentPath = new Path(); 
            currentPath.rewind();
            invalidate();
            break;
        }
        return true;
    }

    // method to get bitmap
    public Bitmap getMainBitmap() {
        return mainBitmap;
    }
    // method to set bitmap
    public void setMainBitmap(Bitmap mpt) {
        mainBitmap = mpt;
        mainCanvas = new Canvas(mainBitmap);
        postInvalidate();
    }
    public void onClickUndo () { 
        if (paths.size()>0) 
        { 
           undonePaths.add(paths.remove(paths.size()-1));
           invalidate();
         }
    }
    public void onClickRedo (){
        if (undonePaths.size()>0) 
        { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            invalidate();
        } 
    }
}

我刚刚发现case MotionEvent.ACTION_UP:case MotionEvent.ACTION_MOVE:的行mainCanvas.drawPath(currentPath, currentpathPaint);不应该在那里。它似乎重新绘制了位图和画布上的路径。不确定我是否说正确的安卓术语。

最新更新