Android: digital signature using Bezier Android: digital signature using Bezier android android

Android: digital signature using Bezier


Change draw method in Bezier class to:

public void draw(Canvas canvas, Paint paint, float startWidth, float endWidth) {    float originalWidth = paint.getStrokeWidth();    float widthDelta = endWidth - startWidth;    for (int i = 0; i < drawSteps; i++) {        float t = ((float) i) / drawSteps;        float tt = t * t;        float ttt = tt * t;        float u = 1 - t;        float uu = u * u;        float uuu = uu * u;        float x = uuu * startPoint.x;        x += 3 * uu * t * getControlPointOne().x;        x += 3 * u * tt * getControlPointTwo().x;        x += ttt * endPoint.x;        float y = uuu * startPoint.y;        y += 3 * uu * t * getControlPointOne().y;        y += 3 * u * tt * getControlPointTwo().y;        y += ttt * endPoint.y;        paint.setStrokeWidth(startWidth + ttt * widthDelta);        canvas.drawPoint(x, y, paint);    }    paint.setStrokeWidth(originalWidth);}


You need to see how many points are drawn in Bezier class and add them up.

From your code: You are collecting 4 points and draw a Bezier curve over them. This means that the algorithm - by design - will miss half of the sampled points.

Other options:1. Create your own Bezier curve or lower order (say - order 3) - and then you'll miss only 1/3 of the points. This kinda renders the issue useless, as you want to conserve less data than sampled.2. Create a high order Bezier curve that can approximate the whole signature.

You can, however, try to figure out what points you would like to select in order to get a Bezier curve which is closer to the signature : select the top of the letter 'l' as an end point of one Bezier curve and the start of another will yield better results.


You can use simple

code

public class MySignatureView extends View {private Path mPath;private Paint mPaint;private Bitmap mBitmap;private Canvas mCanvas;private int bgColor;private float curX, curY;private boolean isDragged = false;private static final int TOUCH_TOLERANCE = 4;private static final int STROKE_WIDTH = 2;public MySignatureView(Context context) {    super(context);    init();}public MySignatureView(Context context, AttributeSet attrs) {    super(context, attrs);    init();}public MySignatureView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    init();}private void init() {    setFocusable(true);    bgColor = Color.WHITE;    mPath = new Path();    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    mPaint.setColor(bgColor ^ 0x00FFFFFF);    mPaint.setStyle(Paint.Style.STROKE);    mPaint.setStrokeWidth(STROKE_WIDTH);}public void setSigColor(int color) {    mPaint.setColor(color);}public void setSigColor(int a, int r, int g, int b) {    mPaint.setARGB(a, r, g, b);}public void clearSig() {    if (mCanvas != null) {        mCanvas.drawColor(bgColor);        mCanvas.drawPaint(mPaint);        mPath.reset();        invalidate();    }}public Bitmap getImage() {    return this.mBitmap;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {    int bitW = mBitmap != null ? mBitmap.getWidth() : 0;    int bitH = mBitmap != null ? mBitmap.getWidth() : 0;    if (bitW >= w && bitH >= h) {        return;    }    if (bitW < w)        bitW = w;    if (bitH < h)        bitH = h;    Bitmap newBitmap = Bitmap.createBitmap(bitW, bitH,            Bitmap.Config.ARGB_8888);    Canvas newCanvas = new Canvas();    newCanvas.setBitmap(newBitmap);    if (mBitmap != null) {        newCanvas.drawBitmap(mBitmap, 0, 0, null);    }    mBitmap = newBitmap;    mCanvas = newCanvas;}@Overrideprotected void onDraw(Canvas canvas) {    canvas.drawBitmap(mBitmap, 0, 0, mPaint);    canvas.drawPath(mPath, mPaint);}@Overridepublic boolean onTouchEvent(MotionEvent event) {    float x = event.getX();    float y = event.getY();    switch (event.getAction()) {    case MotionEvent.ACTION_DOWN:        touchDown(x, y);        break;    case MotionEvent.ACTION_MOVE:        touchMove(x, y);        break;    case MotionEvent.ACTION_UP:        touchUp();        break;    }    invalidate();    return true;}private void touchDown(float x, float y) {    mPath.reset();    mPath.moveTo(x, y);    curX = x;    curY = y;    isDragged = false;}private void touchMove(float x, float y) {    float dx = Math.abs(x - curX);    float dy = Math.abs(y - curY);    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {        mPath.quadTo(curX, curY, (x + curX) / 2, (y + curY) / 2);        curX = x;        curY = y;        isDragged = true;    }}private void touchUp() {    if (isDragged) {        mPath.lineTo(curX, curY);    } else {        mPath.lineTo(curX+2, curY+2);    }    mCanvas.drawPath(mPath, mPaint);    mPath.reset();}  }