-4

i have the coding for draw the user signature.now i need the coding for save that signature in database and i need to compare the signature is correct or not. you can see my coding for draw signature on screen

import android.app.Activity;
import android.content.Context;
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.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;

public class sign extends Activity {
  LinearLayout content;
  signature pnlpanel;
  Button btn,btn1;
@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);

   content = (LinearLayout) findViewById(R.id.linear);
   pnlpanel = new signature(this, null);
   pnlpanel.setBackgroundColor(Color.WHITE);
   content.addView(pnlpanel, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

   btn = (Button) findViewById(R.id.bt);
   btn.setOnClickListener(new OnClickListener() {         
      public void onClick(View v) {
         pnlpanel.clear();
      }
   });

   btn1 = (Button) findViewById(R.id.button);
   btn1.setOnClickListener(new OnClickListener() {         
      public void onClick(View v) {

       switch(v.getId())
    {
    case R.id.linear:
  //db.open();
  //if(equals(linear));

      }}
   });




}


public class signature extends View {

private static final float STROKE_WIDTH = 5f;

/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;

private Paint paint = new Paint();
private Path path = new Path();

/**
* Optimizes painting by invalidating the smallest possible area.
*/
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() {

// TODO Auto-generated method stub

}

/**
* Erases the signature.
*/
public void clear() {
 path.reset();

 // Repaints the entire view.
 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();

 switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:
     path.moveTo(eventX, eventY);
     lastTouchX = eventX;
     lastTouchY = eventY;
     // There is no end point yet, so don't waste cycles invalidating.
     return true;

   case MotionEvent.ACTION_MOVE:
   case MotionEvent.ACTION_UP:
     // Start tracking the dirty region.
     resetDirtyRect(eventX, eventY);

     // When the hardware tracks events faster than they are delivered, the
     // event will contain a history of those skipped points.
     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);
     }

     // After replaying history, connect the line to the touch point.
     path.lineTo(eventX, eventY);
     break;

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

 // Include half the stroke width to avoid clipping.
 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) {
// TODO Auto-generated method stub

}

/**
* Called when replaying history to ensure the dirty region includes all
* points.
*/
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;
 }
}

    /**
    * Resets the dirty region when the motion event occurs.
    */
    private void resetDirtyRect(float eventX, float eventY) {

     // The lastTouchX and lastTouchY were set when the ACTION_DOWN
     // motion event occurred.
     dirtyRect.left = Math.min(lastTouchX, eventX);
     dirtyRect.right = Math.max(lastTouchX, eventX);
     dirtyRect.top = Math.min(lastTouchY, eventY);
     dirtyRect.bottom = Math.max(lastTouchY, eventY);
    }
    }
}
skaffman
  • 398,947
  • 96
  • 818
  • 769
android
  • 55
  • 1
  • 3
  • 8
  • @tamilmaran - i have quickly formatted the code in your post to make it more readable than it was, but you will need to give it some more attention. Make sure each line is indented by at least 4 spaces, or highlight the whole code block and click the `010101` button above the edit area. – slugster Dec 08 '10 at 10:46
  • I don't think it's a good idea to compare drawn signatures, it's very hard. – Jonas Dec 08 '10 at 12:05

2 Answers2

2

If I were you, I would not worry too much about storing the signature (be it in an image file or a database blob).

The hard part of your project will be to try to match two images and see if they look like the other (because when reproducing the signature, it won't be 100% equal: the whole signature might be a bit bigger, a bit smaller, rotated differently, some letters might have a slightly different shape, ...).

You could start looking at this question or at the neuroph library.

Community
  • 1
  • 1
Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • hello marvinlabs please give the android coding for save the signature as image in database. This is my coding for for save button click. – android Dec 08 '10 at 11:53
  • marvinlabs i could not see the coding.please send full source coding for draw signature and save it into the database – android Dec 08 '10 at 12:01
  • Some google'ing took me there: http://stackoverflow.com/questions/2174875/android-canvas-to-jpg I am sure that by putting some effort into searching for information you will find it... – Vincent Mimoun-Prat Dec 08 '10 at 12:03
  • how to save the signature into the database give me the coding – android Dec 09 '10 at 04:18
2

I found one answer at Android capture signature using Canvas and save in png format.

public class GetSignature extends Activity { 
    LinearLayout mContent;
    signature mSignature;
    Button mClear, mGetSign;
    public static String tempDir;
    public int count = 1;
    public String current = null;
    private Bitmap mBitmap;
    View mView;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tempDir = Environment.getExternalStorageDirectory() + "/" + getResources().getString(R.string.external_dir) + "/";
        prepareDirectory();
        current = count + ".png";

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

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

        mGetSign.setOnClickListener(new OnClickListener() 
        {         
            public void onClick(View v) 
            {
                Log.v("log_tag", "Panel Saved");
                mView.setDrawingCacheEnabled(true);
                mSignature.save(mView);
            }
        });

    }

    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.YELLOW);
             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 (320, 480, Bitmap.Config.RGB_565);;
            }
            Canvas canvas = new Canvas(mBitmap);
            String FtoSave = tempDir + current;
            File file = new File(FtoSave);
            try 
            {
                FileOutputStream mFileOutStream = new FileOutputStream(file);
                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);
            }
            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();

             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);
        }
    }//signature
}
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880