Как реализовать сенсорный сглаживание изображения в Android?

Я уже видел fingurePaint.java из демоверсий API. Я хочу реализовать сенсорный плавный ластик, чтобы стереть части изображения касанием переместить в 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 ответа

Решение

Сначала объявите вашу краску со всем свойством в вашем конструкторе.

Напишите этот код в вашем методе 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)
        }
    }

Не лучше ли перевернуть это дело? Просто нарисуйте изображение фоновым цветом, и, в конце концов, при необходимости объедините эти слои.

Определите временный холст и растровое изображение, затем нарисуйте ваш путь или линию, обведите, рисуйте что-нибудь на сенсорных событиях, а затем передайте это временное растровое изображение на холст в 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);
Другие вопросы по тегам