2012-10-10 104 views
4

我創建一個應用程序來繪製在畫布上。爲了繪製,我將筆的顏色設置爲黑色。橡皮擦在Android設備上查看

爲筆按鈕

int black = Color.BLACK; 
mDrawPaint = new DrawPaint(Capture.this, null,black); 

其中DrawPaint延伸查看

我們創造橡皮擦我只是改變了筆的顏色爲白色即畫布的背景色。像這樣

的橡皮擦按鈕

int white = Color.WHITE; 
mDrawPaint = new DrawPaint(Capture.this, null,white); 

但同樣,如果我選擇具有畫筆顏色黑色筆按鈕,在畫布上繪製的東西,它再次自動重繪以前畫我刪除它以前畫的畫。橡皮擦也消除了一個大的矩形區域。請解釋我發生了什麼問題。謝謝。

這裏是DrawPaint構造

public DrawPaint(Context context, AttributeSet attrs, int color) { 

    super(context, attrs); 
    this.destroyDrawingCache(); 
    paint.setAntiAlias(true); 
    paint.setColor(color); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    paint.setStrokeWidth(STROKE_WIDTH); 

} 




    public boolean onTouchEvent(MotionEvent event) { 

     eventX = event.getX(); 
     eventY = event.getY(); 
     button1.setEnabled(true); 

     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      path.moveTo(eventX, eventY); 
      lastTouchX = eventX; 
      lastTouchY = eventY; 
      return true; 

     case MotionEvent.ACTION_MOVE: 

     case MotionEvent.ACTION_UP: 

      resetDirtyRect(eventX, eventY); 
      int historySize = event.getHistorySize(); 
      for (int i = 0; i < historySize; i++) { 
       float historicalX = event.getHistoricalX(i); 
       float historicalY = event.getHistoricalY(i); 
       expandDirtyRect(historicalX, historicalY); 
       path.lineTo(historicalX, historicalY); 
      } 
      path.lineTo(eventX, eventY); 
      break; 

     default: 
      debug("Ignored touch event: " + event.toString()); 
      return false; 
     } 

     invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH), 
       (int) (dirtyRect.top - HALF_STROKE_WIDTH), 
       (int) (dirtyRect.right + HALF_STROKE_WIDTH), 
       (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); 

     lastTouchX = eventX; 
     lastTouchY = eventY; 

     return true; 
    } 
+0

可以顯示的onTouchEvent()方法... – SilentKiller

+0

亞..現在,我在我的問題插入。 –

回答

3

對於橡皮擦,你可以使用此代碼...

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

和有關方彩概率...

檢查了這一點。 。 這是畫布繪製擦除最好的例子,模糊和浮雕效果...

public class FingerText extends Activity 
    implements ColorPickerDialog.OnColorChangedListener {  

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(new MyView(this)); 

    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    //this is the line that sets the initial pen color 
    mPaint.setColor(inkColor); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(2); 
} 



private Paint  mPaint; 
private Bitmap  mBitmap; 
private boolean    inkChosen; 
private int bgColor = 0xFFFFFFFF; //set initial bg color var to white 
private int inkColor = 0xFF000000; //set initial ink color var to black 

public void colorChanged(int color) { 
    //This is the implementation of the interface from colorpickerdialog.java 

    if (inkChosen){ 
      mPaint.setColor(color); 
      inkColor = color; 
    } 
    else { 
      mBitmap.eraseColor (color); 
      bgColor = color; 
      //set the color to the user's last ink color choice 
      mPaint.setColor(inkColor); 
    } 



} 

public class MyView extends View { 



    private Canvas mCanvas; 
    private Path mPath; 
    private Paint mBitmapPaint; 

    public MyView(Context c) { 
     super(c); 

     mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); 

     //this sets the bg color for the bitmap 
     mBitmap.eraseColor (bgColor); 
     mCanvas = new Canvas(mBitmap); 
     mPath = new Path(); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     //this is the line that changes the bg color in the initial canvas 
      canvas.drawColor(bgColor); 
     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

     canvas.drawPath(mPath, mPaint); 
    } 

    private float mX, mY; 
    private static final float TOUCH_TOLERANCE = 4; 

    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); 
     // commit the path to our offscreen 
     mCanvas.drawPath(mPath, mPaint); 
     // kill this so we don't double draw 
     mPath.reset(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     float x = event.getX(); 
     float y = event.getY(); 

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

private static final int BG_COLOR_ID = Menu.FIRST; 
private static final int INK_MENU_ID = Menu.FIRST + 1; 
private static final int CLEAR_MENU_ID = Menu.FIRST + 2; 
private static final int ERASER_MENU_ID = Menu.FIRST + 3; 
private static final int SEND_MENU_ID = Menu.FIRST + 4; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    super.onCreateOptionsMenu(menu); 

    menu.add(0, BG_COLOR_ID, 0, "Background Color").setShortcut('3', 'b'); 
    menu.add(0, INK_MENU_ID, 0, "Ink Color").setShortcut('4', 'c'); 
    menu.add(0, CLEAR_MENU_ID, 0, "Clear All").setShortcut('5', 'e'); 
    menu.add(0, ERASER_MENU_ID, 0, "Eraser").setShortcut('6', 'x'); 
    menu.add(0, SEND_MENU_ID, 0, "Send").setShortcut('7', 's'); 

    /**** Is this the mechanism to extend with filter effects? 
    Intent intent = new Intent(null, getIntent().getData()); 
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE); 
    menu.addIntentOptions(
          Menu.ALTERNATIVE, 0, 
          new ComponentName(this, NotesList.class), 
          null, intent, 0, null); 
    *****/ 
    return true; 
} 

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 
    super.onPrepareOptionsMenu(menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    mPaint.setXfermode(null); 
    mPaint.setAlpha(0xFF); 

    switch (item.getItemId()) { 

      case BG_COLOR_ID: 
        new ColorPickerDialog(this, this, mPaint.getColor()).show(); 
        inkChosen = false; 
        return true; 
     case INK_MENU_ID: 
      new ColorPickerDialog(this, this, mPaint.getColor()).show(); 
      //remember the user's last ink choice color so we can revert after eraser 
      //to background color change -- otherwise ink is last bg color 
      inkColor = mPaint.getColor(); 
      inkChosen = true; 
      return true; 
     case CLEAR_MENU_ID: 
      mBitmap.eraseColor (bgColor); 
      return true; 
     case ERASER_MENU_ID: 
      //set pen color to bg color for 'erasing' 
      mPaint.setColor(bgColor); 
      return true; 
     case SEND_MENU_ID: 
        /* TODO need to decide whether to save image locally 
        * and how to make it available if so. really only need to 
        * save if we want to let users view later, or pick a 
        * previous message to send again 
        */ 

        // this try-catch block creates a private file and an 
        // inputstream pointing to it for reading 
      FileInputStream ifs; 
          try { 
            FileOutputStream fs = openFileOutput("message_image", Context.MODE_PRIVATE); 
            mBitmap.compress(CompressFormat.PNG, 100, fs); 
            ifs = openFileInput("message_image"); 
          } catch (FileNotFoundException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
            return true; 
          } 
            // inserts file pointed to by ifs into image gallery 
          String url = Images.Media.insertImage(getContentResolver(), 
            BitmapFactory.decodeStream(ifs), 
            "Message image1", "Message image"); 

            // alternative: inserts mBitmap into image gallery 
/*    String url = Images.Media.insertImage(getContentResolver(), 
           mBitmap, "Message image1", "Message image"); 
*/ 
            // creates the Intent to open the messaging app 
            // with the image at url attached 
      Intent sendIntent = new Intent(Intent.ACTION_SEND); 
      sendIntent.putExtra("sms_body", "Message created using FingerText"); 
      sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url)); 
      sendIntent.setType("image/png"); 
      startActivity(sendIntent); 
        /* TODO delete the image from the content provider 
        * following line deletes the image, but too soon! 
        */ 
//    getContentResolver().delete(Uri.parse(url), null, null); 


      //this resets canvas after send 
      //could also reset to last user settings w/o var resets 
      bgColor = 0xFFFFFFFF; //set bg color var back to white 
      inkColor = 0xFF000000; //set ink color var back to black 
      mBitmap.eraseColor (bgColor); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

}

+0

你爲什麼需要mCanvas?用onDraw()處理canvas還不夠嗎?在我看來,你正在畫同樣的東西兩次。 – Laviniux

+0

謝謝你沉默的殺手。是啊..爲什麼mCanvas?你能解釋一下嗎? –

+0

只是暫時油畫時,我畫和)路徑將膨脹視圖的畫布上時Action_UP電話... – SilentKiller