【问题标题】:how to implement finger eraser in android?如何在android中实现手指橡皮擦?
【发布时间】:2012-03-19 07:00:23
【问题描述】:

我已经准备了一个绘画应用程序。在我的应用程序中,我们可以绘制任何东西。它工作正常。在这里我想准备手指擦除以擦除绘画。为此我准备了以下代码,

这是在触摸,

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

这是我在自定义视图中的绘制方法,

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

        }

    }

如果有绘制的油漆,我想擦除我触摸的油漆,请帮助我。

【问题讨论】:

    标签: android android-canvas android-custom-view


    【解决方案1】:

    它可能对你有帮助:

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

    【讨论】:

    【解决方案2】:

    画布不支持橡皮擦,而位图支持。

    基本解决方法流程:

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

    【讨论】:

      猜你喜欢
      • 2011-12-06
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      相关资源
      最近更新 更多