如何在安卓手机上用手指擦除图片

5

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

我有一个覆盖在图像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));

无法工作。


你的画笔是白色的。至少你需要一种透明的颜料。 - njzk2
可能是在Android上使用透明画笔绘图的重复问题。 - njzk2
你想要擦除的图像在哪里绘制的?它似乎不在你要擦除的画布上? - njzk2
@njzk2 在 onWindowFocusChanged 中,我创建了一个 Bitmap,并用它创建了一个 Canvas,然后在图像上使用 setImageBitmap。 - Ilario
@njzk2 是的,图像被设置为要擦除的背景图像。 - Ilario
显示剩余4条评论
2个回答

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

能否计算已擦除的图像百分比? - Ale

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

"and"
private void updatePercentage(float percentage) {

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

感谢大家。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接