2012-09-06 70 views
4

我已經從API演示中看到了fingurePaint.java。我想實現觸摸平滑橡皮擦通過觸摸移動在Android中刪除圖像的部分。如何在android中實現觸摸平滑圖像橡皮擦?

fingurePaint告訴我要實現這個

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

但是這是行不通的刪除圖像。它正在努力抹去通過觸摸繪製的東西。

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

}

所以,請幫助我通過使用觸摸移動來刪除圖像的部分。

在此先感謝。

+0

我可以參考這個例子有一個工作演示http://whats-online.info/science-and-tutorials/137/Android-tutorial-How-to-erase-part-of-bitmap- image-on-touch/ –

回答

0

首先使用構造函數中的所有屬性對您的顏色進行Decal。

寫這樣的代碼在你的的onDraw()方法

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

第二個解決方案:

調用下面的方法在您的TOUCH_MOVE()方法

mBitmap.setPixel (x,y,Color.TRANSPARENT);此方法將改變你的位圖,你必須只傳遞X,Y & 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

顛倒這種情況不是更好嗎?只需在背景顏色上繪製圖像,最後在保存時合併這些圖層,如果需要的話。

+0

在地面有一個圖像。我的意思是我在另一張圖片上有一張圖片,而我正在刪除頂部圖片。如何做到這一點 –

0

定義一個臨時的帆布和位圖,然後畫上的觸摸事件的路徑或直線,圓,像任何東西,然後通過這個臨時位圖在onDraw中畫布時,您的工作將會正常完成,並且如果您想要擦除,請在該臨時畫布上進行擦除。

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