Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 209
Ilario Avatar asked Oct 20 '22 06:10

Ilario


2 Answers

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));
}}
like image 110
Maheesha De Silva Avatar answered Oct 27 '22 01:10

Maheesha De Silva


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

like image 41
Ilario Avatar answered Oct 26 '22 23:10

Ilario