Reputation: 31
I have prepared one paint app.In my app we can draw any thing.It is working fine.Here i want prepare finger erase for erase paint.For that i have prepared following code,
this is on touch,
mMyPaint.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(paintAndEraserFlag==0){
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// path = new Path();
mPath.moveTo(event.getX(), event.getY());
mPath.lineTo(event.getX(), event.getY());
mArryLstPath.add(mPath);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
mPath.lineTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mPath.lineTo(event.getX(), event.getY());
}
}else if(paintAndEraserFlag==1){
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// path = new Path();
System.out.println("in path---");
mPath.moveTo(event.getX(), event.getY());
mPath.lineTo(event.getX(), event.getY());
mArryLstEarser.add(mEraserPath);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
mPath.lineTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mPath.lineTo(event.getX(), event.getY());
}
}
mMyPaint.invalidate();
return true;
}
});
my paint and eraser objects,
mPaint.setDither(true);
mPaint.setColor(0xFFD2691E);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(30);
mEraser.setDither(true);
mEraser.setStyle(Paint.Style.STROKE);
mEraser.setStrokeJoin(Paint.Join.ROUND);
mEraser.setStrokeCap(Paint.Cap.ROUND);
mEraser.setStrokeWidth(15);
mEraser.setColor(0x00000000);
this is my on draw method in custom view,
public void onDraw(Canvas canvas) {
if (myDrawBitmap == null) {
myDrawBitmap = Bitmap.createBitmap(480, 800,
Bitmap.Config.ARGB_8888);
mBmpDrawCanvas = new Canvas(myDrawBitmap);
mIntDrawArray = new int[myDrawBitmap.getWidth()
* myDrawBitmap.getHeight()];
}
if (mBmpDrawCanvas != null) {
myDrawBitmap.getPixels(mIntDrawArray, 0, myDrawBitmap.getWidth(),
0, 0, myDrawBitmap.getWidth(), myDrawBitmap.getHeight());
if (MyEraserActivity.paintAndEraserFlag == 0) {
for (Path path : MyEraserActivity.mArryLstPath) {
mBmpDrawCanvas.drawPath(MyEraserActivity.mPath, mPaint);
}
} else if (MyEraserActivity.paintAndEraserFlag == 1) {
for (Path path : MyEraserActivity.mArryLstEarser) {
mBmpDrawCanvas.drawPath(MyEraserActivity.mEraserPath,
mEraser);
System.out.println("in eraser---");
}
}
if (myDrawBitmap != null)
canvas.drawBitmap(myDrawBitmap, 0, 0, null);
}
}
I want erase paint where i touch if drawn paint is there please help me.
Upvotes: 3
Views: 2166
Reputation: 1029
Canvas does not support eraser while Bitmap does.
Basic workaround flow:
Create another canvas
Create a bitmap
Set that bitmap to that canvas
public void init(int width, int height) {
Log.i(TAG,"init with "+width+"x"+height);
foreground = Bitmap.createBitmap(width, height, Config.ARGB_8888);
cacheCanvas = new Canvas();
cacheCanvas.setBitmap(foreground);
}
Record the touches on that bitmap, including paint and eraser
public boolean onTouchEvent(MotionEvent event) {
// Log.i(TAG,"onTouch detected");
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentStroke = new Stroke();
currentStroke.color = paint;
currentStroke.path.moveTo(eventX, eventY);
currentStroke.path.lineTo(eventX, eventY);
synchronized (strokes) {
strokes.add(currentStroke);
}
lastTouchX = eventX;
lastTouchY = eventY;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// Start tracking the dirty region.
resetDirtyRect(eventX, eventY);
// When the hardware tracks events faster than they are delivered,
// the
// event will contain a history of those skipped points.
int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
if (i == 0) {
lastX = historicalX;
lastY = historicalY;
currentStroke.path.lineTo(historicalX, historicalY);
} else {
currentStroke.path.quadTo(lastX, lastY,
(historicalX + lastX) / 2,
(historicalY + lastY) / 2);
}
}
// After replaying history, connect the line to the touch point.
if(historySize==0){
long duration=event.getEventTime()-event.getDownTime();
float offset=0.1f;
if(duration<300){
offset=50.0f/duration;
}
currentStroke.path.lineTo(eventX+offset, eventY+offset);
}else{
currentStroke.path.lineTo(eventX, eventY);
}
synchronized (strokes) {
strokes.add(currentStroke);
}
break;
default:
// Log.i(TAG,"Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
float width = paint.getStrokeWidth() / 2;
invalidate((int) (dirtyRect.left - width),
(int) (dirtyRect.top - width), (int) (dirtyRect.right + width),
(int) (dirtyRect.bottom + width));
lastTouchX = eventX;
lastTouchY = eventY;
return true;
}
Draw that bitmap on the canvas of your View
protected void onDraw(Canvas canvas) {
// Log.i(TAG,"onDraw called");
synchronized (strokes) {
if (strokes.size() > 0) {
for (Stroke s : strokes) {
cacheCanvas.drawPath(s.path, s.color);
}
canvas.drawBitmap(foreground, 0, 0, null);
strokes.clear();
}
}
}
Upvotes: 0
Reputation: 1733
It may helps you:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Upvotes: 1