2013-08-20 128 views
4

我是android新手。我正在做一個應用程序,它可以用手指擦除畫布上的位圖。像手指油漆橡皮擦。我想計算已擦除區域的百分比(例如60%已從完整圖像中刪除)。請幫助我這樣做..在此先感謝..如何計算android中位圖擦除區域的百分比?

我試過一些方法。它總是給我0%。它不工作。請參閱該方法的代碼的底部..

自定義視圖

public class MyView extends View 
{ 
    private final Paint mPaint; 
    private Bitmap mBitmap; 
    private Canvas mCanvas; 
    private final Path mPath; 
    private final Paint mBitmapPaint; 
    private Bitmap eraseableBitmap; 

    public MyView(Context context) 
    { 
     super(context); 
     if (Build.VERSION.SDK_INT >= 11) 
     { 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     } 
     mPaint = new Paint(); 
     mPath = new Path(); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
    } 

    protected void PaintObjectInit() 
    { 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(30); 
    } 

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

     try 
     { 
      //mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
      eraseableBitmap = 
       BitmapFactory.decodeResource(this.getResources(), R.drawable.tharu_rena_over).copy(
        Bitmap.Config.ARGB_8888, true); 

      eraseableBitmap = getResizedBitmap(eraseableBitmap, h, w); 

      mCanvas = new Canvas(eraseableBitmap); 
     } 
     catch (Exception e) 
     { 
      // TODO: handle exception 
      e.printStackTrace(); 
     } 
    } 

    public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) 
    { 
     int width = bm.getWidth(); 
     int height = bm.getHeight(); 
     float scaleWidth = ((float) newWidth)/width; 
     float scaleHeight = ((float) newHeight)/height; 
     // CREATE A MATRIX FOR THE MANIPULATION 
     Matrix matrix = new Matrix(); 
     // RESIZE THE BIT MAP 
     matrix.postScale(scaleWidth, scaleHeight); 

     // "RECREATE" THE NEW BITMAP 
     Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); 
     return resizedBitmap; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 

     //canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
     canvas.drawBitmap(eraseableBitmap, 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 
     Toast.makeText(getContext(), "Deleted: " + percentTransparent(eraseableBitmap, 10), Toast.LENGTH_SHORT).show(); 
    } 

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

    static public float percentTransparent(Bitmap bm, int scale) 
    { 

     final int width = bm.getWidth(); 
     final int height = bm.getHeight(); 

     // size of sample rectangles 
     final int xStep = width/scale; 
     final int yStep = height/scale; 

     // center of the first rectangle 
     final int xInit = xStep/2; 
     final int yInit = yStep/2; 

     // center of the last rectangle 
     final int xEnd = width - xStep/2; 
     final int yEnd = height - yStep/2; 

     int totalTransparent = 0; 

     for (int x = xInit; x <= xEnd; x += xStep) 
     { 
      for (int y = yInit; y <= yEnd; y += yStep) 
      { 
       if (bm.getPixel(x, y) == Color.TRANSPARENT) 
       { 
        totalTransparent++; 
       } 
      } 
     } 
     return ((float) totalTransparent)/(scale * scale); 

    } 

} 

內活動課的onCreate

try 
{ 
    MyView myView = new MyView(this); 
    myView.requestFocus(); 
    myView.PaintObjectInit(); 
    // setContentView(myView); 

    LinearLayout upper = (LinearLayout) findViewById(R.id.LinearLayout01); 
    upper.addView(myView); 
} 
catch (Exception e) 
{ 
    // TODO: handle exception 
    e.printStackTrace(); 
} 
+0

我不知道爲什麼它不工作,但你爲什麼不只是調試功能,看看是否所有的變量都正確的像'xStep'或者嘗試1個像素的步驟,並檢查它是否進入for循環,如果是的話,你可以記錄'bm.getPixel(x,y)'。那麼你可能可以自己弄清楚爲什麼它不起作用 –

+0

Thnx,我調試過。它進入循環。總是bm.getPixel(x,y)非零。由於我給它規模10,每次迭代100次。所以我經歷了大約20次迭代。對於所有這些像素,我獲得了非零值。並且總是把0.0%的東西刪除。我不知道爲什麼。 – ssdehero

+1

您在哪裏將「已擦除」像素設置爲Color.TRANSPARENT? – Martin

回答

1

問題是你沒有打電話給你PaintObjectInit()方法,讓你用默認油漆繪畫,所以在Color.BLACK中畫,而不是Color.TRANSPARENT。在構造函數的底部添加一個PaintObjectInit()的調用,它應該可以工作。

此外,下面創建一個不可變的位圖!見createBitmap。所以,你的位圖永遠不會被修改。您通過繪製路徑以及位圖來隱藏這一事實。

// "RECREATE" THE NEW BITMAP 
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); 
return resizedBitmap; 

試着做一個可變的位圖這樣的 -

// "RECREATE" THE NEW BITMAP 
     Bitmap resizedBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); 
     Canvas c = new Canvas(resizedBitmap); 
     c.setMatrix(matrix); 
     c.drawBitmap(bm, matrix, null); 
     return resizedBitmap; 
+0

沒有。我在我的activity類中調用它,然後將該視圖對象添加到佈局。所以我的擦除部分正在工作。 – ssdehero

+0

如果它是視圖的受保護方法,你如何從activity類調用'PaintObjectInit()'?你是否對這個代碼之外的對象的狀態做了其他更改? – iagreen

+0

兩者都在同一個包中。請參閱已編輯的問題... – ssdehero