Android Canvas撤消和重做Bitmap

时间:2013-10-30 14:59:18

标签: android bitmap android-canvas

我在画布上遇到撤消和重做操作的问题。 我注意到下面的代码可以工作,如果我不在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();
        } 
    }
}

1 个答案:

答案 0 :(得分:2)

我刚发现mainCanvas.drawPath(currentPath, currentpathPaint);case MotionEvent.ACTION_UP:的{​​{1}}行不应该在那里。它似乎重绘了位图的路径并在画布上。不确定我是否说出了正确的Android术语。