如何在android中实现触摸流畅的图像橡皮擦?

时间:2012-09-06 09:51:24

标签: android touch erase

我已经从API演示中看到了fingurePaint.java。我想通过在android中触摸移动来实现触摸平滑橡皮擦来擦除部分图像。

fingurePaint告诉我实现这个

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

但这不能消除图像。它正在努力抹去触摸绘制的东西。

public class SandboxView extends View implements OnTouchListener {
    public  final Bitmap bitmap;
    private final int width;
    private final int height;
    private Matrix transform = new Matrix();

    private Vector2D position = new Vector2D();
    private float scale = 1;
    private float angle = 0;
    public boolean isInitialized = false;
    private TouchManager touchManager = new TouchManager(2);
    final GestureDetector mGesDetect;


    // Debug helpers to draw lines between the two touch points
    private Vector2D vca = null;
    private Vector2D vcb = null;
    private Vector2D vpa = null;
    private Vector2D vpb = null;

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;
    private Path    mPath;
    private Canvas  mCanvas;
    private Paint       mPaint;
    private Paint   mBitmapPaint;
    public SandboxView(Context context, Bitmap bitmap) {
        super(context);

        this.bitmap = bitmap;
        this.width = bitmap.getWidth();
        this.height = bitmap.getHeight();
        this.mGesDetect = new GestureDetector(context, new DoubleTapGestureDetector());

        setOnTouchListener(this);
    }


    private  float getDegreesFromRadians(float angle) {
        return (float)(angle * 360.0 / Math.PI);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isInitialized) {
            Bitmap mBitmap = bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
            mPaint = new Paint();
            mPath = new Path();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(0xFFFF0000);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(12);
            mPaint.setAlpha(0);
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            mPaint.setAntiAlias(true);

            mBitmapPaint = new Paint(Paint.DITHER_FLAG);


            int w = getWidth();
            int h = getHeight();
            position.set(w / 2, h / 2);
            isInitialized = true;
        }
        if(isEraser==1){
            canvas.drawColor(80000000);


            canvas.drawBitmap(bitmap, transform, mBitmapPaint);

            canvas.drawPath(mPath, mPaint);
        }
        else{


        Paint paint = new Paint();

        transform.reset();
        transform.postTranslate(-width / 2.0f, -height / 2.0f);
        transform.postRotate(getDegreesFromRadians(angle));
        transform.postScale(scale, scale);
        transform.postTranslate(position.getX(), position.getY());

        canvas.drawBitmap(bitmap, transform, paint);

        try {
            /*paint.setColor(0xFF007F00);
            canvas.drawCircle(vca.getX(), vca.getY(), 64, paint);
            paint.setColor(0xFF7F0000);
            canvas.drawCircle(vcb.getX(), vcb.getY(), 64, paint);

            paint.setColor(0xFFFF0000);
            canvas.drawLine(vpa.getX(), vpa.getY(), vpb.getX(), vpb.getY(), paint);
            paint.setColor(0xFF00FF00);
            canvas.drawLine(vca.getX(), vca.getY(), vcb.getX(), vcb.getY(), paint);*/




        }
        catch(NullPointerException e) {
            // Just being lazy here...
        }
        }
    }

    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);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();
    }




    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if(isEraser ==1){
            float x = event.getX();
            float y = event.getY();

            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));


            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;
        }
        else{
        vca = null;
        vcb = null;
        vpa = null;
        vpb = null;
        mGesDetect.onTouchEvent(event);

        try {
            touchManager.update(event);

            if (touchManager.getPressCount() == 1) {
                vca = touchManager.getPoint(0);
                vpa = touchManager.getPreviousPoint(0);
                position.add(touchManager.moveDelta(0));
            }
            else {
                if (touchManager.getPressCount() == 2) {
                    vca = touchManager.getPoint(0);
                    vpa = touchManager.getPreviousPoint(0);
                    vcb = touchManager.getPoint(1);
                    vpb = touchManager.getPreviousPoint(1);

                    Vector2D current = touchManager.getVector(0, 1);
                    Vector2D previous = touchManager.getPreviousVector(0, 1);
                    float currentDistance = current.getLength();
                    float previousDistance = previous.getLength();

                    if (previousDistance != 0) {
                        scale *= currentDistance / previousDistance;
                    }

                    angle -= Vector2D.getSignedAngleBetween(current, previous);
                }
            }

            invalidate();
        }
        catch(Throwable t) {
            // So lazy...
        }
        return true;
        }
    }
    class DoubleTapGestureDetector extends GestureDetector.SimpleOnGestureListener {


        @Override
        public boolean onDoubleTap(MotionEvent e) {
            colorseekbar.setVisibility(View.INVISIBLE);
            opacityseekbar.setVisibility(View.INVISIBLE);
            return true;
        }
    }

}

所以请帮我用触摸移动来擦除图像部分。

提前致谢。

3 个答案:

答案 0 :(得分:0)

反转这种情况不是更好吗?只需在背景颜色上绘制图像,然后在保存时,根据需要合并这些图层。

答案 1 :(得分:0)

首先使用构造函数中的所有属性声明您的绘图。

将此代码写入 onDraw()方法

@Override
protected void onDraw(Canvas canvas) 
   {
    System.out.println("come in on draw......");
    canvas.drawColor(Color.TRANSPARENT);
    canvas.drawBitmap(mBitmap, 0, 0, mPaint);
            if(eraser==true)
               mPaint.setColor(Color.TRANSPARENT):
            else
               mPaint.setColor(Color.RED):
    canvas.drawPath(mPath, mPaint);

    super.dispatchDraw(canvas);
}

第二个解决方案:

touch_move()方法

中调用以下方法

mBitmap.setPixel(x,y,Color.TRANSPARENT); 此方法会更改您的位图,您必须只传递 X,Y&颜色

public void changeBitmap(int x, int y, Bitmap mBitmap)
{
 Bitmap tempBitmap = Bitmap.createBitmap(mBitmap); //Edited code
 tempBitmap.setPixel(x, y, Color.TRANSPARENT);
}



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;
            changeBitmap(x, y, your_bitmap)
        }
    }

答案 2 :(得分:0)

定义一个临时画布和位图,然后在触摸事件上绘制你的路径或线,圈,图像,然后将这个临时位图传递给onDraw中的画布,你的工作将正确完成,如果你想要擦除,那么你做在那张临时画布上擦除。

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        TemporaryBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
        TemporaryCanvas = new Canvas(TemporaryBitmap);
}
TemporaryCanvas.drawColor(0, PorterDuff.Mode.clear);
public void onDraw(Canvas canv){
canv.drawBitmap(TemporaryBitmap, matrix, paint);