How to implement touch image eraser in Android?

I have already seen fingurePaint.java from the API demos. I want to implement a touch eraser to erase parts of an image using touch movement in Android.

fingurePaint told me to implement this

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 

But it does not work to erase the image. It works to erase something that is painted by touch.

 public class SandboxView extends View implements OnTouchListener { public final Bitmap bitmap; private final int width; private final int height; private Matrix transform = new Matrix(); private Vector2D position = new Vector2D(); private float scale = 1; private float angle = 0; public boolean isInitialized = false; private TouchManager touchManager = new TouchManager(2); final GestureDetector mGesDetect; // Debug helpers to draw lines between the two touch points private Vector2D vca = null; private Vector2D vcb = null; private Vector2D vpa = null; private Vector2D vpb = null; private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private Path mPath; private Canvas mCanvas; private Paint mPaint; private Paint mBitmapPaint; public SandboxView(Context context, Bitmap bitmap) { super(context); this.bitmap = bitmap; this.width = bitmap.getWidth(); this.height = bitmap.getHeight(); this.mGesDetect = new GestureDetector(context, new DoubleTapGestureDetector()); setOnTouchListener(this); } private float getDegreesFromRadians(float angle) { return (float)(angle * 360.0 / Math.PI); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!isInitialized) { Bitmap mBitmap = bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mPaint = new Paint(); mPath = new Path(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(0xFFFF0000); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(12); mPaint.setAlpha(0); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mPaint.setAntiAlias(true); mBitmapPaint = new Paint(Paint.DITHER_FLAG); int w = getWidth(); int h = getHeight(); position.set(w / 2, h / 2); isInitialized = true; } if(isEraser==1){ canvas.drawColor(80000000); canvas.drawBitmap(bitmap, transform, mBitmapPaint); canvas.drawPath(mPath, mPaint); } else{ Paint paint = new Paint(); transform.reset(); transform.postTranslate(-width / 2.0f, -height / 2.0f); transform.postRotate(getDegreesFromRadians(angle)); transform.postScale(scale, scale); transform.postTranslate(position.getX(), position.getY()); canvas.drawBitmap(bitmap, transform, paint); try { /*paint.setColor(0xFF007F00); canvas.drawCircle(vca.getX(), vca.getY(), 64, paint); paint.setColor(0xFF7F0000); canvas.drawCircle(vcb.getX(), vcb.getY(), 64, paint); paint.setColor(0xFFFF0000); canvas.drawLine(vpa.getX(), vpa.getY(), vpb.getX(), vpb.getY(), paint); paint.setColor(0xFF00FF00); canvas.drawLine(vca.getX(), vca.getY(), vcb.getX(), vcb.getY(), paint);*/ } catch(NullPointerException e) { // Just being lazy here... } } } private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(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 touch_up() { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, mPaint); mPath.reset(); } @Override public boolean onTouch(View v, MotionEvent event) { if(isEraser ==1){ float x = event.getX(); float y = event.getY(); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } else{ vca = null; vcb = null; vpa = null; vpb = null; mGesDetect.onTouchEvent(event); try { touchManager.update(event); if (touchManager.getPressCount() == 1) { vca = touchManager.getPoint(0); vpa = touchManager.getPreviousPoint(0); position.add(touchManager.moveDelta(0)); } else { if (touchManager.getPressCount() == 2) { vca = touchManager.getPoint(0); vpa = touchManager.getPreviousPoint(0); vcb = touchManager.getPoint(1); vpb = touchManager.getPreviousPoint(1); Vector2D current = touchManager.getVector(0, 1); Vector2D previous = touchManager.getPreviousVector(0, 1); float currentDistance = current.getLength(); float previousDistance = previous.getLength(); if (previousDistance != 0) { scale *= currentDistance / previousDistance; } angle -= Vector2D.getSignedAngleBetween(current, previous); } } invalidate(); } catch(Throwable t) { // So lazy... } return true; } } class DoubleTapGestureDetector extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { colorseekbar.setVisibility(View.INVISIBLE); opacityseekbar.setVisibility(View.INVISIBLE); return true; } } 

}

So please help me remove parts of the image using the touch stroke.

Thanks in advance.

+4
source share
3 answers

First declare your paint with all the property in your constructor.

Enter this code in your onDraw () method

 @Override protected void onDraw(Canvas canvas) { System.out.println("come in on draw......"); canvas.drawColor(Color.TRANSPARENT); canvas.drawBitmap(mBitmap, 0, 0, mPaint); if(eraser==true) mPaint.setColor(Color.TRANSPARENT): else mPaint.setColor(Color.RED): canvas.drawPath(mPath, mPaint); super.dispatchDraw(canvas); } 

second solution:

call the method below in the touch_move () method

mBitmap.setPixel (x, y, Color.TRANSPARENT); This method will change your bitmap, which you should pass only X, Y and COLOR

 public void changeBitmap(int x, int y, Bitmap mBitmap) { Bitmap tempBitmap = Bitmap.createBitmap(mBitmap); //Edited code tempBitmap.setPixel(x, y, Color.TRANSPARENT); } private void touch_move(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; changeBitmap(x, y, your_bitmap) } } 
0
source

Isn't it better to invert this case? Just draw your image with the background color and, finally, when saving, merge these layers if necessary.

0
source

Define a temporary canvas and bitmap, then draw your path or line, circle, do something on touch events, and then transfer this temporary bitmap to the canvas in onDraw, your work will be done correctly, and also if you want to erase , do your erasure on this temporary canvas.

  protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); TemporaryBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444); TemporaryCanvas = new Canvas(TemporaryBitmap); } TemporaryCanvas.drawColor(0, PorterDuff.Mode.clear); public void onDraw(Canvas canv){ canv.drawBitmap(TemporaryBitmap, matrix, paint); 
0
source

Source: https://habr.com/ru/post/1432684/


All Articles