Ilario
Ilario

Reputation: 6079

How to erase image with finger in Android

I'm developing an app that need the feature in object.

I have an Image A that cover an Image B. With finger I need to erase the Image A to show the Image B. Erase must follow your finger flowing image A

I'm trying some code but still I couldn't erase the image A. this is the code that i'm using to draw a line on image (_imageToErase is Image 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;
}

This code produce only a line that follow the finger but not erase the image.

How to modify this code to erase the image? Thanks

EDIT

The link suggested in comments not solved my problem. Simply add this line:

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

not work for me.

Upvotes: 5

Views: 4747

Answers (2)

Maheesha De Silva
Maheesha De Silva

Reputation: 31

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

Upvotes: 2

Ilario
Ilario

Reputation: 6079

Finally I found a library that works very well for me and implementation is pretty simple

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

Import library in your project and then in 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"/>

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

Thanks everybody

Upvotes: 1

Related Questions