如何在Android中用手指擦除图像

时间:2015-07-20 13:19:43

标签: java android canvas bitmap

我正在开发一个需要对象功能的应用。

我有一个覆盖图像B的图像A.用手指我需要擦除图像A以显示图像B. 擦除必须遵循手指流动的图像A

我尝试了一些代码,但我仍然无法删除图像A.这是我用来在图像上绘制一条线的代码(_imageToErase是图片A):

Canvas canvas;
Paint paint;
float downx = 0, downy = 0, upx = 0, upy = 0;
ImageView _imageToErase;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.g_layout);

    _imageToErase = (ImageView) findViewById(R.id.image_to_erase);

    _imageToErase.setOnTouchListener(this);
}

@Override
public void onWindowFocusChanged(boolean hasFocus){

    int width = _imageToErase.getWidth();
    int height = _imageToErase.getHeight();

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    canvas = new Canvas(bitmap);
    paint = new Paint();
    paint.setColor(Color.WHITE);
    paint.setStrokeWidth(25);
    paint.setAntiAlias(true);
    _imageToErase.setImageBitmap(bitmap);
}

public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();

    switch (action){
        case MotionEvent.ACTION_DOWN:
            downx = event.getX();
            downy = event.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            upx = event.getX();
            upy = event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            _imageToErase.invalidate();
            downx = upx;
            downy = upy;
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
        default:
            break;
    }

    return true;
}

此代码仅产生一条跟随手指的线但不会擦除图像。

如何修改此代码以删除图像?感谢

修改

评论中建议的链接无法解决我的问题。只需添加以下行:

 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));

不适合我。

2 个答案:

答案 0 :(得分:2)

PaintView.java

public class PaintView extends View implements View.OnTouchListener {

    private static final String TAG = "PaintView";
    Bitmap Bitmap1, Bitmap2;
    Bitmap Transparent;
    int X = -100;
    int Y = -100;
    Canvas c2;
    private boolean isTouched = false;

    Paint paint = new Paint();

    Path drawPath = new Path();

public PaintView(Context context) {
    super(context);
    setFocusable(true);
    setFocusableInTouchMode(true);
    this.setOnTouchListener(this);

    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    int width = metrics.widthPixels;
    int height = metrics.heightPixels;

    Transparent = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.cake1);
    Bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.cake2);

    c2 = new Canvas();
    c2.setBitmap(Transparent);
    c2.drawBitmap(Bitmap2, 0, 0, paint);

    paint.setAlpha(0);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    paint.setAntiAlias(true);
}

private static Point getDisplaySize(final Display display) {
    final Point point = new Point();
    point.x = display.getWidth();
    point.y = display.getHeight();
    return point;
}

@Override
protected void onDraw(Canvas canvas) {
    System.out.println("onDraw");

    if(isTouched)
    {
        canvas.drawBitmap(Bitmap1, 0, 0, null);

    }
    canvas.drawBitmap(Transparent, 0, 0, null);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    isTouched = true;
    X = (int) event.getX();
    Y = (int) event.getY();

    paint.setStrokeWidth(60);

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            drawPath.moveTo(X, Y);
            c2.drawPath(drawPath, paint);
            break;
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(X, Y);
            c2.drawPath(drawPath, paint);
            break;
        case MotionEvent.ACTION_UP:
            drawPath.lineTo(X, Y);
            c2.drawPath(drawPath, paint);
            drawPath.reset();
            count=0;
            break;
        default:
            return false;
    }

    invalidate();
    return true;}}class Point {
float x, y;

@Override
public String toString() {
    return x + ", " + y;
}}

MainActivity.java

public class MainActivity extends Activity {

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

答案 1 :(得分:1)

最后我找到了一个非常适合我的库,实现非常简单

https://github.com/winsontan520/Android-WScratchView

导入项目中的库,然后导入layout.xml

 <com.winsontan520.WScratchView
  android:layout_width="287dp"
  android:layout_height="212dp"
  android:layout_centerHorizontal="true"
  android:layout_marginTop="80dp"
  android:adjustViewBounds="true"
  android:scaleType="centerInside"
  android:id="@+id/image_to_erase"/>
onCreate:

中的

_imageToErase = (WScratchView) findViewById(R.id.image_to_erase);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_erase);

_imageToErase.setScratchBitmap(bitmap);


_imageToErase.setOnScratchCallback(new WScratchView.OnScratchCallback() {
        @Override
        public void onScratch(float percentage) {
            updatePercentage(percentage);
        }

        @Override
        public void onDetach(boolean fingerDetach) {
            if (mPercentage > 40) {
                _imageToErase.setScratchAll(true);
                updatePercentage(100);
            }
        }
    });

private void updatePercentage(float percentage) {

    mPercentage = percentage;
 //   System.out.println("percentage = "+percentage);
}

谢谢大家