问题
I'm new to android. I'm doing an application which can erase the bitmap on canvas using finger. Something like finger paint eraser. I want to calculate the percentage of erased area (eg. 60% has been erased from complete image). Please help me to do this.. Thanks in advance..
I tried some method. It always give me 0%. Its not working. See the bottom of the code for that method..
Customized View
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);
}
}
Inside Activity Class 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();
}
回答1:
The problem is you are failing to call your PaintObjectInit()
method, so you are painting with a default paint, so painting in Color.BLACK
instead of Color.TRANSPARENT
. Add a call to PaintObjectInit()
at the bottom of you constructor and it should work.
Also, the following creates an immutable bitmap! See createBitmap. So, your bitmap is never being modified. You are hiding this fact on the user interface by drawing the path as well as the bitmap.
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
Try making a mutable bitmap like this --
// "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;
来源:https://stackoverflow.com/questions/18336113/how-to-calculate-the-percentage-of-erased-area-of-a-bitmap-in-android