Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android FingerPaint sample does not draw dot?

Tags:

android

Fingerpaint example in sample android api demo does not draw dot/point by touching finger on screen. In code they have used Path to draw line, is there any way to draw circle or point using path?

public class MyView extends View {
    // int bh = originalBitmap.getHeight();
    // int bw = originalBitmap.getWidth();

    public MyView(Context c, int w, int h) {
        super(c);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        // Bitmap mBitmap =
        // Bitmap.createScaledBitmap(originalBitmap,200,200,true);
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        //mBitmapPaint.setColor(Color.YELLOW);
        //mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // mBitmap = Bitmap.createBitmap(bw, bh, Bitmap.Config.ARGB_8888);
        // mCanvas = new Canvas(mBitmap);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        //canvas.drawColor(customColor);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        canvas.drawPath(mPath, mPaint);
    }

    // //////************touching evants for painting**************///////
    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 5;

    private void touch_start(float x, float y) {
        //mCanvas.drawCircle(x, y, progress+1, mPaint); 

        mPath.reset();          
        mPath.moveTo(x, y);
        //mPaint.setStyle(Paint.Style.FILL);
        //mPath.addCircle(x, y, (float) (progress+0.15), Direction.CW);  
        mCanvas.drawPath(mPath, mPaint);
        mX = x;
        mY = y;
        //mPaint.setStyle(Paint.Style.STROKE);

    }

    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);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        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;
    } // end of touch events for image
}

Here is the code, what should i edit in this code to able to draw dot/point on finertouch?

like image 372
Nouman Bhatti Avatar asked Jun 22 '13 13:06

Nouman Bhatti


2 Answers

is there any way to draw circle or point using path?

Instead of trying to do that use the method drawPoint(float x, float y, Paint paint) in the class Canvas.

To use it in the API demo you will need to change 3 things:

  1. Have a private boolean mDrawPoint; in the MyView class to differentiate between a tap and a slide.
  2. Set mDrawPoint to true in touch_start() and to false in touch_move() if the path is changed (that is in the if statement).
  3. In touch_up() check the value of mDrawPoint. If it is false do what the function did before and if it is true then draw the point on the canvas: mCanvas.drawPoint(mX, mY, mPaint);

New version of touch_up():

private void touch_up() {
    if(mDrawPoint == true) {
        mCanvas.drawPoint(mX, mY, mPaint);          
    } else {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }
}

when i move up my finger after drawing a line it automatically draws a point next to it, where the line ended. And when i starts a new line/curve the previously drawn line would remove /clear from the canvas leaving only dots behind that were drawn.

You don't need any more modification than what's in my answer. You probably forgot to implement a part of it.

I had the same problem when trying it up and solved it before posting my answer. It was caused because you draw on two different canvas, on given to the onDraw method, which gets lost when your finger gets up and the other is mCanvas, which is where the line is saved in touch_up. This is why touch_up has an if:

If we didn't move the finger (just tapped) then we draw the point to the mCanvas so that it is still there on the next onDraw (onDraw draws the mCanvas to the canvas it receives as argument so that older lines and points painted on mCanvas are still visible).

If we moved the finger then we save the path that was drawn to the canvas passed to onDraw to the mCanvas so that it is still present after getting the finger up.

The problem you have comes from the else part of the touch_up function never getting executed so that on touch_up a point gets drawn regardless of whether it should and the path never gets committed to mCanvas and thus disappear the next time onDraw is called.

This most likely stem from you setting mDrawPoint to true in touch_start() as I said in point 2. but forgetting to set mDrawPoint up to false in touch_move as I also said in point 2.

Here is what my touch_move looks like:

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;
        mDrawPoint = false;
        }
    }
like image 108
Julien Rousseau Avatar answered Sep 22 '22 00:09

Julien Rousseau


A very late reply, but it would be easier to use mCanvas.drawPoint(x, y, mPaint); in touch_start.

like image 27
user3482211 Avatar answered Sep 20 '22 00:09

user3482211