android - 如何在android中实现触摸平滑图像橡皮擦?

标签 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;
        }
    }

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

提前致谢。

最佳答案

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

将此代码写入您的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 & COLOR

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

关于android - 如何在android中实现触摸平滑图像橡皮擦?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12297396/

相关文章:

android - 像这张图片一样的自定义弹出菜单

javascript - D3.js缩放和触摸设备平滑度

javascript - JQuery 触摸启用可拖动侧边栏?

c++ - 这个 map 删除安全吗?

java - Spring-Roo 删除 Mysql,尽管 hibernate.hbm2ddl.auto

c++ - std::map - 删除最后一个元素

android - 我在库模块中有 .aar 文件,如何在应用程序模块中使用它?

android - Json 从 URL 在 android 中解析

android - 如何在调用新的异步任务时终止以前的任务

directx - 如何在桌面应用程序中调出 Windows 8 屏幕键盘