pearmak pearmak - 2 months ago 49
Android Question

android canvas remove previous path being drawn

I am making a drawing app, and would like to implement an undo function to remove the immediate previous drawn path.

Coding:



private HashMap<Integer, Path> pathMap; // current Paths being drawn
private HashMap<Integer, Point> previousPointMap; // current Points
private Bitmap bitmap; // drawing area for display or saving
private Canvas bitmapCanvas; // used to draw on bitmap
private Paint paintScreen; // use to draw bitmap onto screen
private Paint paintLine; // used to draw lines onto bitmap

public DrawView(Context context, AttributeSet attrs)
{
super(context, attrs); // pass context to View's constructor
this.context_new=context;

paintScreen = new Paint(); // used to display bitmap onto screen

// set the initial display settings for the painted line
paintLine = new Paint();
paintLine.setAntiAlias(true); // smooth edges of drawn line
paintLine.setColor(Color.BLACK); // default color is black
paintLine.setStyle(Paint.Style.STROKE); // solid line
paintLine.setStrokeWidth(5); // set the default line width
paintLine.setStrokeCap(Paint.Cap.ROUND); // rounded line ends
pathMap = new HashMap<Integer, Path>();
previousPointMap = new HashMap<Integer, Point>();
} // end DrawView constructor

@Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
for (Integer key : pathMap.keySet())
canvas.drawPath(pathMap.get(key), paintLine);
}

// called when the user finishes a touch
private void touchEnded(int lineID)
{
Path path = pathMap.get(lineID); // get the corresponding Path
bitmapCanvas.drawPath(path, paintLine); // draw to bitmapCanvas
path.reset(); // reset the Path
rememberLineId = lineID;
} // end method touch_ended

//undo
private void undo()
{
Path path = pathMap.get(rememberLineId); // get the corresponding Path
pathMap.remove(rememberLineId);
bitmapCanvas.clearPath(path, paintLine);
path.reset(); // reset the Path
}


Question:



However, it seems there is no
bitmapCanvas.clearPath
this method? If then how could it be modified?

Codes Amended:



Declarations:

private Bitmap bitmap; // drawing area for display or saving
private Canvas bitmapCanvas; // used to draw on bitmap
private Paint paintScreen; // use to draw bitmap onto screen
private Paint paintLine; // used to draw lines onto bitmap
private HashMap<Integer, Path> pathMap; // current Paths being drawn
private HashMap<Integer, Point> previousPointMap; // current Points

private Bitmap bitmapBackup;


OnSizeChanged

@Override
public void onSizeChanged(int w, int h, int oldW, int oldH)
{
super.onSizeChanged(w, h, oldW, oldH);
DoodlzViewWidth = w;
DoodlzViewHeight = h;

bitmapBackup = Bitmap.createBitmap(getWidth(), DoodlzViewHeight, Bitmap.Config.ARGB_8888);
bitmap = Bitmap.createBitmap(getWidth(), DoodlzViewHeight, Bitmap.Config.ARGB_8888);

bitmapCanvas = new Canvas(bitmap);
bitmap .eraseColor(Color.WHITE); // erase the BitMap with white
bitmapBackup.eraseColor(Color.WHITE);
}


FirsttoBackup method, will invoke when the below TouchedStart performs

public void firsttobackup()
{
bitmapBackup=bitmap;
Toast message = Toast.makeText(getContext(), "backuped 123", Toast.LENGTH_SHORT);
message.show(); //THIS TOAST CAN BE SUCESSFULLY PRESENTED when touching screen starting to draw
}


OnDraw

@Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
for (Integer key : pathMap.keySet())
canvas.drawPath(pathMap.get(key), paintLine);


}

OnTouchEvent

@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getActionMasked(); // event type
int actionIndex = event.getActionIndex(); // pointer (i.e., finger)

if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN)
{
firsttobackup(); //TOAST CAN SHOW "BACKUP 123"

touchStarted(event.getX(actionIndex), event.getY(actionIndex),
event.getPointerId(actionIndex));
}


Undo: user pressing the undo button will invoke this

public void undo()
{
bitmap = bitmapBackup.copy(Bitmap.Config.ARGB_8888, true);
bitmapCanvas = new Canvas(bitmap);
}


Question revised:



A method
firsttobackup()
is used now such that bitmapBackup would set = bitmap when executing
OnTouchEvent
touchStarted
. I have put a toast in it and it is sucesfully to be presented "backup 123" when user press the screen and started to draw.

When user clicks undo button, it will invoke the
undo
method, but now pressing the undo button, no action can be seen...why?

Thanks!!

Answer

I think the easiest way for doing that is having 2 bitmaps (1 additional backup bitmap for restoring previous state).

You need to save previous state of a bitmap before you start new drawings.

Here is how I would modify your code:

  private HashMap<Integer, Path> pathMap; // current Paths being drawn
  private HashMap<Integer, Point> previousPointMap; // current Points
  private Bitmap bitmap; // drawing area for display or saving
  private Bitmap bitmapBackup; 
  private Canvas bitmapCanvas; // used to draw on bitmap
  private Canvas bitmapBackupCanvas; 


  // remember last bitmap before new drawings...    
     private void touchStarted()   
     {
        bitmapBackupCanvas.drawBitmap(bitmap, 0, 0, null);
     } 
  // called when the user finishes a touch    
     private void touchEnded(int lineID)   
     {
        Path path = pathMap.get(lineID); // get the corresponding Path
        bitmapCanvas.drawPath(path, paintLine); // draw to bitmapCanvas
        path.reset(); // reset the Path
        rememberLineId = lineID;
     } // end method touch_ended

  //undo       
     private void undo()
     {
        Path path = pathMap.get(rememberLineId); // get the corresponding Path
        pathMap.remove(rememberLineId);
        bitmapCanvas.drawBitmap(bitmapBackup, 0, 0, null); // restore from backup
        path.reset(); // reset the Path
     } 
Comments