Android: цифровая подпись с использованием Bezier

enter image description here
Я пытаюсь сделать две ничьей цифровую подпись, используя Bezier, как показано выше на изображении. Когда я прикасаюсь и пытаюсь рисовать линию, тогда результат является точечной линией, но не становится непрерывной. Простая подпись, сделанная с помощью простая подпись но я хочу создать более гладкую кривую, используя Безье с сенсорным давлением. попробовал эту ссылку

SignatureViewDemo.java

    public class SignatureViewDemo extends View {
        private int color = Color.BLACK;
        private Bitmap m_Bitmap;
        private final Paint m_BorderPaint;
        private Canvas m_Canvas;
        private Point m_CropBotRight;
        private Point m_CropTopLeft;
        private float m_CurrentX;
        private float m_CurrentY;
        private final float m_DesiredDash;
        private float m_LastWidth = 6.5F;
        private Paint m_PenPaint;
        private int m_PointIndex = 0;
        private ArrayList<Point> m_Points = new ArrayList<Point>();
        private final float m_StrokeWidth;
        boolean m_Empty;



    public SignatureViewDemo(Context paramContext) {

        this(paramContext, null);
    }

    public SignatureViewDemo(Context paramContext,
            AttributeSet paramAttributeSet) {
        this(paramContext, paramAttributeSet, 0);
    }

    public SignatureViewDemo(Context paramContext,
            AttributeSet paramAttributeSet, int paramInt) {
        super(paramContext, paramAttributeSet, paramInt);
        setFocusable(true);
        this.m_PenPaint = new Paint();
        this.m_PenPaint.setAntiAlias(true);
        this.m_PenPaint.setColor(Color.BLACK);
        this.m_PenPaint.setStrokeWidth(5.0F);
        this.m_PenPaint.setStrokeJoin(Paint.Join.ROUND);
        this.m_PenPaint.setStrokeCap(Paint.Cap.ROUND);
        this.m_CurrentY = (0.0F / 0.0F);
        this.m_CurrentX = (0.0F / 0.0F);
        this.m_StrokeWidth = 5.0F;
        this.m_DesiredDash = 10.0F;
        this.m_BorderPaint = new Paint();
        this.m_BorderPaint.setColor(Color.BLACK);
        this.m_BorderPaint.setStyle(Paint.Style.STROKE);
        this.m_BorderPaint.setStrokeWidth(this.m_StrokeWidth);
    }

    public void addBezier(Bezier paramBezier, float paramFloat1,
            float paramFloat2) {
        if (this.m_Bitmap == null) {
            this.m_Bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
                    Bitmap.Config.ARGB_8888);
            this.m_Canvas = new Canvas(this.m_Bitmap);
        }
        paramBezier.draw(this.m_Canvas, this.m_PenPaint, paramFloat1,
                paramFloat2);
    }

    public void addPoint(Point paramPoint) {
        if ((paramPoint.getX() < this.m_CropTopLeft.getX())
                && (paramPoint.getX() >= 0.0F))
            this.m_CropTopLeft.setX(paramPoint.getX());
        if ((paramPoint.getY() < this.m_CropTopLeft.getY())
                && (paramPoint.getY() >= 0.0F))
            this.m_CropTopLeft.setY(paramPoint.getY());
        if ((paramPoint.getX() > this.m_CropBotRight.getX())
                && (paramPoint.getX() <= this.m_Canvas.getWidth()))
            this.m_CropBotRight.setX(paramPoint.getX());
        if ((paramPoint.getY() > this.m_CropBotRight.getY())
                && (paramPoint.getY() <= this.m_Canvas.getHeight()))
            this.m_CropBotRight.setY(paramPoint.getY());
        this.m_Points.add(paramPoint);
        drawPoints();
    }

    // public void clear() {
    // if (this.m_Canvas == null)
    // this.m_Canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    // invalidate();
    // // return;
    // }

    public void clear() {
        if (this.m_Canvas == null)
            return;
        while (m_Empty) {
            m_Canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            m_Empty = true;
            invalidate();
            return;
        }
    }

    public void drawBitmap(Bitmap paramBitmap) {
        clear();
        if ((paramBitmap != null) && (this.m_Canvas != null)
                && (this.m_Canvas.getWidth() != 0)
                && (this.m_Canvas.getHeight() != 0)) {
            Matrix localMatrix = new Matrix();
            localMatrix.setRectToRect(
                    new RectF(0.0F, 0.0F, paramBitmap.getWidth(), paramBitmap
                            .getHeight()),
                    new RectF(0.0F, 0.0F, this.m_Canvas.getWidth(),
                            this.m_Canvas.getHeight()),
                    Matrix.ScaleToFit.CENTER);
            this.m_Canvas.drawBitmap(paramBitmap, localMatrix, null);
            m_Empty = false;
        }
        invalidate();
    }

    public void drawPoints() {
        if ((m_Points.size() >= 4)
                && (4 + this.m_PointIndex <= this.m_Points.size())) {
            Point localPoint1 = (Point) this.m_Points.get(this.m_PointIndex);
            Point localPoint2 = (Point) this.m_Points
                    .get(1 + this.m_PointIndex);
            Point localPoint3 = (Point) this.m_Points
                    .get(2 + this.m_PointIndex);
            Point localPoint4 = (Point) this.m_Points
                    .get(3 + this.m_PointIndex);
            Bezier localBezier = new Bezier(localPoint1, localPoint2,
                    localPoint3, localPoint4);
            localBezier.setColor(Color.GREEN);
            float f = strokeWidth(8.0F / localPoint4.velocityFrom(localPoint1));
            addBezier(localBezier, this.m_LastWidth, f);
            invalidate();
            this.m_LastWidth = f;
            this.m_PointIndex = (3 + this.m_PointIndex);
            m_Empty = false;
        }
    }

    public boolean isEmpty() {
        return m_Empty;
    }

    public Bitmap getBitmap() {
        return this.m_Bitmap;
    }

    public int getColor() {
        return this.color;
    }

    protected void onDraw(Canvas paramCanvas) {
        if (this.m_Bitmap != null)
            paramCanvas.drawBitmap(this.m_Bitmap, 0.0F, 0.0F, null);
    }

    protected void onMeasure(int paramInt1, int paramInt2) {
        int i = View.MeasureSpec.getSize(paramInt1);
        int j = View.MeasureSpec.getSize(paramInt2);
        this.m_CropTopLeft = new Point(i, j);
        this.m_CropBotRight = new Point(0.0F, 0.0F);
        setMeasuredDimension(i, j);
    }

    protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3,
            int paramInt4) {
        Bitmap localBitmap = Bitmap.createBitmap(paramInt1, paramInt2,
                Bitmap.Config.ARGB_8888);
        this.m_Canvas = new Canvas(localBitmap);
        float f1 = 2.0F * (this.m_Canvas.getWidth() + this.m_Canvas.getHeight() - 2.0F * this.m_StrokeWidth);
        float f2 = f1
                * this.m_DesiredDash
                / (Math.round(f1 / (4.0F * this.m_DesiredDash)) * (4.0F * this.m_DesiredDash));
        Paint localPaint = this.m_BorderPaint;
        float[] arrayOfFloat = new float[2];
        arrayOfFloat[0] = f2;
        arrayOfFloat[1] = f2;
        localPaint.setPathEffect(new DashPathEffect(arrayOfFloat, f2 / 2.0F));
        clear();
        if (this.m_Bitmap != null) {
            Rect localRect = new Rect(0, 0, this.m_Canvas.getWidth(),
                    this.m_Canvas.getHeight());
            this.m_Canvas.drawBitmap(this.m_Bitmap, null, localRect, null);
            m_Empty = false;
        }
        this.m_Bitmap = localBitmap;
    }

    public boolean onTouchEvent(MotionEvent paramMotionEvent) {
        int i = 0xFF & paramMotionEvent.getAction();
        if (i == 0) {
            this.m_CurrentX = paramMotionEvent.getX();
            this.m_CurrentY = paramMotionEvent.getY();
            addPoint(new Point(this.m_CurrentX, this.m_CurrentY,
                    paramMotionEvent.getEventTime()));
            getParent().requestDisallowInterceptTouchEvent(true);
        }
        // while (m_Empty) {
        if ((i == 1) || (i == 3)) {
            this.m_CurrentY = (0.0F / 0.0F);
            this.m_CurrentX = (0.0F / 0.0F);
            this.m_Points.clear();
            this.m_PointIndex = 0;
            getParent().requestDisallowInterceptTouchEvent(false);
        }
        // if ((this.m_Points.size() < 4) || (4 + this.m_PointIndex >
        // this.m_Points.size()))
        // while (1 + this.m_PointIndex <= this.m_Points.size())
        drawPoints();
        if ((i == 2) || (i == 1)) {
            for (int j = 0; j < paramMotionEvent.getHistorySize(); j++)
                addPoint(new Point(paramMotionEvent.getHistoricalX(j),
                        paramMotionEvent.getHistoricalY(j),
                        paramMotionEvent.getHistoricalEventTime(j)));
            addPoint(new Point(paramMotionEvent.getX(),
                    paramMotionEvent.getY(), paramMotionEvent.getEventTime()));

        }
        // }
        return true;
    }

    public void setColor(int paramInt) {
        this.color = Color.BLACK;
    }

    public Point getCropBotRight() {
        return this.m_CropBotRight;
    }

    public Point getCropTopLeft() {
        return this.m_CropTopLeft;
    }

    // public float strokeWidth(float paramFloat) {
    // if (paramFloat > 11.0F)
    // paramFloat = 10.0F;
    // if (paramFloat < 5.0F)
    // paramFloat = 6.0F;
    // return paramFloat;
    // }

    public float strokeWidth(float paramFloat) {
        if (paramFloat > 11.0F)
            paramFloat = 10.0F;
        while (m_Empty) {
            if (paramFloat < 5.0F)
                paramFloat = 6.0F;
            return paramFloat;
        }
        return paramFloat;
    }

}

Point.java

    private long time;
    private float x;
    private float y;

    public Point(float paramFloat1, float paramFloat2) {
        this.x = paramFloat1;
        this.y = paramFloat2;
    }

    public Point(float paramFloat1, float paramFloat2, long paramLong) {
        this.x = paramFloat1;
        this.y = paramFloat2;
        this.time = paramLong;
    }

    protected float distanceTo(Point paramPoint) {
        float f1 = this.x - paramPoint.getX();
        float f2 = this.y - paramPoint.getY();
        return FloatMath.sqrt(f1 * f1 + f2 * f2);
    }

    public long getTime() {
        return this.time;
    }

    public float getX() {
        return this.x;
    }

    public float getY() {
        return this.y;
    }

    public void setX(float paramFloat) {
        this.x = paramFloat;
    }

    public void setY(float paramFloat) {
        this.y = paramFloat;
    }

    public float velocityFrom(Point paramPoint) {
            return distanceTo(paramPoint) / (this.time - paramPoint.time);
    }
}

Bezier.java

public class Bezier {
private Point controlPointOne;
private Point controlPointTwo;
private int drawSteps;
private Point endPoint;
private int mColor;
private Point startPoint;

public Bezier() {
}

public Bezier(Point paramPoint1, Point paramPoint2, Point paramPoint3,
        Point paramPoint4) {
    this.startPoint = paramPoint1;
    this.controlPointOne = paramPoint2;
    this.controlPointTwo = paramPoint3;
    this.endPoint = paramPoint4;
    this.drawSteps = ((int) (paramPoint1.distanceTo(paramPoint2)
            + paramPoint2.distanceTo(paramPoint3) + paramPoint3
            .distanceTo(paramPoint4)));
}

public void draw(Canvas paramCanvas, Paint paramPaint, float paramFloat1,
        float paramFloat2) {
    float f1 = paramFloat2 - paramFloat1;
    for (int i = 0; i < this.drawSteps; i++) {
        float f2 = i / this.drawSteps;
        float f3 = f2 * f2;
        float f4 = f3 * f2;
        float f5 = 1.0F - f2;
        float f6 = f5 * f5;
        float f7 = f6 * f5;
        float f8 = f7 * this.startPoint.getX() + f2 * (3.0F * f6)
                * this.controlPointOne.getX() + f3 * (3.0F * f5)
                * this.controlPointTwo.getX() + f4 * this.endPoint.getX();
        float f9 = f7 * this.startPoint.getY() + f2 * (3.0F * f6)
                * this.controlPointOne.getY() + f3 * (3.0F * f5)
                * this.controlPointTwo.getY() + f4 * this.endPoint.getY();
        paramPaint.setColor(getColor());
        paramPaint.setStrokeWidth(paramFloat1 + f4 * f1);
        paramCanvas.drawPoint(f8, f9, paramPaint);
    }
}

public int getColor() {
    return this.mColor;
}

public Point getControlPointOne() {
    return this.controlPointOne;
}

public Point getControlPointTwo() {
    return this.controlPointTwo;
}

public int getDrawSteps() {
    return this.drawSteps;
}

public Point getEndPoint() {
    return this.endPoint;
}

public Point getStartPoint() {
    return this.startPoint;
}

public void setColor(int paramInt) {
    this.mColor = Color.BLACK;
}

public void setControlPointOne(Point paramPoint) {
    this.controlPointOne = paramPoint;
}

public void setControlPointTwo(Point paramPoint) {
    this.controlPointTwo = paramPoint;
}

public void setDrawSteps(int paramInt) {
    this.drawSteps = paramInt;
}

public void setEndPoint(Point paramPoint) {
    this.endPoint = paramPoint;
}

public void setStartPoint(Point paramPoint) {
    this.startPoint = paramPoint;
}

}

Ответ 1

Измените метод draw в классе Безье на:

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

Ответ 2

Вам нужно посмотреть, сколько очков нарисовано в классе Безье и добавить их.

Из вашего кода: вы собираете 4 балла и рисуете кривую Безье над ними. Это означает, что алгоритм - по дизайну - пропустит половину выбранных точек.

Другие варианты: 1. Создайте свою собственную кривую Безье или нижний порядок (скажем - порядок 3) - и тогда вы пропустите только 1/3 очков. Этот вид делает проблему бесполезной, так как вы хотите сохранить меньше данных, чем выборку. 2. Создайте кривую Безье Безье, которая может аппроксимировать всю подпись.

Однако вы можете попытаться выяснить, какие точки вы хотите выбрать, чтобы получить кривую Безье, которая ближе к сигнатуре: выберите верхнюю часть буквы "l" в качестве конечной точки одной кривой Безье и начало другого даст лучшие результаты.

Ответ 3

Вы можете использовать простой

код

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

@Override
protected 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;
}

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

@Override
public 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();
}

  }

Ответ 4

Вы можете использовать это, я также добавил xml внизу:

import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Images;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class SignatureCapture extends Activity {

    public LinearLayout mContent;
    public signature mSignature;
    public Button mClear, mGetSign, mCancel;
    public static String tempDir;
    public int count = 1;
    public String current = null;
    public static Bitmap mBitmap;
    public View mView;
    public File mypath;
    private String uniqueId;
    private EditText yourName;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.signature);

        // tempDir = Environment.getExternalStorageDirectory() + "/" +
        // getResources().getString(R.string.external_dir) + "/";
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
        // File directory =
        // cw.getDir(getResources().getString(R.string.external_dir),
        // Context.MODE_PRIVATE);

        File directory = new File(Environment.getExternalStorageDirectory()
                + "/GLP_Images");

        if (!directory.exists())

            directory.mkdir(); // directory is created;

        // prepareDirectory();
        uniqueId = getTodaysDate() + "_" + getCurrentTime();
        current = uniqueId + ".png";
        mypath = new File(directory, current);

        mContent = (LinearLayout) findViewById(R.id.linearLayout);
        mSignature = new signature(this, null);
        mSignature.setBackgroundColor(Color.WHITE);
        mContent.addView(mSignature, LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT);
        mClear = (Button) findViewById(R.id.clear);
        mGetSign = (Button) findViewById(R.id.getsign);
        mGetSign.setEnabled(false);
        mCancel = (Button) findViewById(R.id.cancel);
        mView = mContent;

        // yourName = (EditText) findViewById(R.id.yourName);

        mClear.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Log.v("log_tag", "Panel Cleared");
                mSignature.clear();
                mGetSign.setEnabled(false);
            }
        });

        mGetSign.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Log.v("log_tag", "Panel Saved");
                // boolean error = captureSignature();
                // if(error){
                mView.setDrawingCacheEnabled(true);
                mSignature.save(mView);
                // Bundle b = new Bundle();
                // b.putString("status", "done");
                /*
                 * Intent intent = new
                 * Intent(SignatureCapture.this,SigntuareCaptureActivity.class);
                 * // intent.putExtra("imagePath",mypath);
                 * startActivity(intent); //intent.putExtra("status", "done");
                 * //setResult(RESULT_OK,intent); finish(); // }
                 */

                AlertDialog.Builder dialog = new AlertDialog.Builder(
                        SignatureCapture.this);
                dialog.setMessage("Details saved");
                dialog.setPositiveButton("OK",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                    int which) {
                                dialog.dismiss();
                            }
                        });
                dialog.show();
            }
        });

        mCancel.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Log.v("log_tag", "Panel Canceled");
                Bundle b = new Bundle();
                b.putString("status", "cancel");
                Intent intent = new Intent();
                intent.putExtras(b);
                setResult(RESULT_OK, intent);
                finish();
            }
        });

    }

    @Override
    protected void onDestroy() {
        Log.w("GetSignature", "onDestory");
        super.onDestroy();
    }

    // private boolean captureSignature()
    // {
    //
    // boolean error = false;
    // String errorMessage = "";
    //
    //
    // if(yourName.getText().toString().equalsIgnoreCase(""))
    // {
    // errorMessage = errorMessage + "Please enter your Name\n";
    // error = true;
    // }
    //
    // if(error)
    // {
    // Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
    // toast.setGravity(Gravity.TOP, 105, 50);
    // toast.show();
    // }
    //
    // return error;
    // }

    private String getTodaysDate() {
        final Calendar c = Calendar.getInstance();
        int todaysDate = (c.get(Calendar.YEAR) * 10000)
                + ((c.get(Calendar.MONTH) + 1) * 100)
                + (c.get(Calendar.DAY_OF_MONTH));
        Log.w("DATE:", String.valueOf(todaysDate));
        return (String.valueOf(todaysDate));
    }

    private String getCurrentTime() {

        final Calendar c = Calendar.getInstance();
        int currentTime = (c.get(Calendar.HOUR_OF_DAY) * 10000)
                + (c.get(Calendar.MINUTE) * 100) + (c.get(Calendar.SECOND));
        Log.w("TIME:", String.valueOf(currentTime));
        return (String.valueOf(currentTime));

    }

    private boolean prepareDirectory() {
        try {
            if (makedirs()) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(
                    this,
                    "Could not initiate File System.. Is Sdcard mounted properly?",
                    1000).show();
            return false;
        }
    }

    private boolean makedirs() {
        File tempdir = new File(tempDir);
        if (!tempdir.exists())
            tempdir.mkdirs();

        if (tempdir.isDirectory()) {
            File[] files = tempdir.listFiles();
            for (File file : files) {
                if (!file.delete()) {
                    System.out.println("Failed to delete " + file);
                }
            }
        }
        return (tempdir.isDirectory());
    }

    public class signature extends View {
        private static final float STROKE_WIDTH = 5f;
        private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
        private Paint paint = new Paint();
        private Path path = new Path();

        private float lastTouchX;
        private float lastTouchY;
        private final RectF dirtyRect = new RectF();

        public signature(Context context, AttributeSet attrs) {
            super(context, attrs);
            paint.setAntiAlias(true);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(STROKE_WIDTH);
        }

        public void save(View v) {
            Log.v("log_tag", "Width: " + v.getWidth());
            Log.v("log_tag", "Height: " + v.getHeight());
            if (mBitmap == null) {
                mBitmap = Bitmap.createBitmap(mContent.getWidth(),
                        mContent.getHeight(), Bitmap.Config.RGB_565);
            }
            Canvas canvas = new Canvas(mBitmap);
            try {

                FileOutputStream mFileOutStream = new FileOutputStream(mypath);

                v.draw(canvas);
                mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream);
                mFileOutStream.flush();
                mFileOutStream.close();
                String url = Images.Media.insertImage(getContentResolver(),
                        mBitmap, "title", null);
                // Log.v("log_tag","url: " + url);

                // //In case you want to delete the file
                // boolean deleted = mypath.delete();
                // Log.v("log_tag","deleted: " + mypath.toString() + deleted);
                // //If you want to convert the image to string use base64
                // converter

            } catch (Exception e) {
                Log.v("log_tag", e.toString());
            }
        }

        public void clear() {
            path.reset();
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawPath(path, paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float eventX = event.getX();
            float eventY = event.getY();
            mGetSign.setEnabled(true);

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(eventX, eventY);
                lastTouchX = eventX;
                lastTouchY = eventY;
                return true;

            case MotionEvent.ACTION_MOVE:

            case MotionEvent.ACTION_UP:

                resetDirtyRect(eventX, eventY);
                int historySize = event.getHistorySize();
                for (int i = 0; i < historySize; i++) {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                    path.lineTo(historicalX, historicalY);
                }
                path.lineTo(eventX, eventY);
                break;

            default:
                debug("Ignored touch event: " + event.toString());
                return false;
            }

            invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                    (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

            lastTouchX = eventX;
            lastTouchY = eventY;

            return true;
        }

        private void debug(String string) {
        }

        private void expandDirtyRect(float historicalX, float historicalY) {
            if (historicalX < dirtyRect.left) {
                dirtyRect.left = historicalX;
            } else if (historicalX > dirtyRect.right) {
                dirtyRect.right = historicalX;
            }

            if (historicalY < dirtyRect.top) {
                dirtyRect.top = historicalY;
            } else if (historicalY > dirtyRect.bottom) {
                dirtyRect.bottom = historicalY;
            }
        }

        private void resetDirtyRect(float eventX, float eventY) {
            dirtyRect.left = Math.min(lastTouchX, eventX);
            dirtyRect.right = Math.max(lastTouchX, eventX);
            dirtyRect.top = Math.min(lastTouchY, eventY);
            dirtyRect.bottom = Math.max(lastTouchY, eventY);
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/header_bg"
        android:gravity="center"
        android:text="Signature"
        android:textColor="@android:color/white"
        android:textSize="20dp"
        android:textStyle="bold" />

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".30"
            android:text="Cancel"
            android:visibility="gone" />

        <Button
            android:id="@+id/clear"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Clear" />

        <Button
            android:id="@+id/getsign"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Save" />
    </LinearLayout>

</LinearLayout>