如何在安卓系统中实现手指橡皮擦?

3

我准备了一个绘画应用程序,在我的应用中我们可以画任何东西,它运行良好。在这里,我想为擦除绘画准备手指擦除。为此,我已经准备了以下代码:

这是触摸事件:

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;

            }
        });

我的绘画和橡皮擦对象,
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);

这是我的自定义视图中的onDraw方法。
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);

        }

    }

我想要擦掉我触碰到的油漆,如果油漆已经干了,请帮忙。

2个回答

1

这可能会对您有所帮助:

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

我正在使用您在此处提到的相同代码,但是这段代码存在一些问题,您能否查看我在stackoverflow上发布的问题http://stackoverflow.com/questions/16229496/eraser-with-porterduff-mode-clear-always-draws-a-transparent-line - AndroidDev

0

Canvas不支持橡皮擦,而Bitmap支持。

基本解决方案流程:

  1. 创建另一个画布

  2. 创建位图

  3. 将该位图设置为该画布

    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);
    }
    
  4. 记录该位图上的触摸事件,包括画笔和橡皮擦

    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;
    }
    
  5. 在您的视图的画布上绘制该位图

    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();
        }
    }
    }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接