How to implement a finger eraser in android?

I have prepared one drawing application. In my application, we can draw any thing. It works great. I want to prepare a paint remover finger removal. For this, I have prepared the following code,

it's a 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 paintwork 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 drawing 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 to remove paint where I touch, if the painted paint is there, please help me.

+3


source to share


2 answers


This might help you:



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

      

+1


source


Canvas doesn't support an eraser, but Bitmap does.

Main workaround thread:



  • Create another canvas

  • Create a bitmap

  • Set this bitmap to this 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);
    }
    
          

  • Write down the strokes on this bitmap, including the eraser 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 this bitmap onto 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();
        }
    }
    }
    
          

0


source







All Articles