Capture Signature Using FingerPaint in Android

Posted By : Arpit Sharma | 15-Jan-2013

Capture signature using fingerpaint in android

Today I will blog on how to Capture Signature using FingerPaint in android, you have to follow the given pionts in order to capture signature.

  • Create a new SignatureCapture project and replace main.xml code from the given one.

 

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

    <Button
        android:id="@+id/getSign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Get Signature" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

</LinearLayout>
  • Create a new CaptureSignature Activity class and also create capturesignature.xml for layout.

CaptureSignature.java

package com.example.signaturecapture;

import android.app.Activity;
import android.os.Bundle;

public class CaptureSignature extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.capturesignature);
	}

}

capturesignature.xml

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

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal" >

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

        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="save" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/mysignature"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </LinearLayout>

</LinearLayout>
  • Now its time to edit MainActivity, initialize the objects and defined their events.

 

package com.example.signaturecapture;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {
	Button b1;
	ImageView signImage;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		b1 = (Button) findViewById(R.id.getSign);
		signImage = (ImageView) findViewById(R.id.imageView1);
		b1.setOnClickListener(onButtonClick);
	}

	Button.OnClickListener onButtonClick = new Button.OnClickListener() {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			
		}
	};
}

  • Now start CaptureSignature activity on a click of button through intent using startActivityForResult(intent) instead of startActivity(intent) and @override onActivityResult method in MainActivity.(Please configure the CaptureSignature activity in AndroidManifest.xml first).

 

package com.example.signaturecapture;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {
	Button b1;
	ImageView signImage;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		b1 = (Button) findViewById(R.id.getSign);
		signImage = (ImageView) findViewById(R.id.imageView1);
		b1.setOnClickListener(onButtonClick);
	}

	Button.OnClickListener onButtonClick = new Button.OnClickListener() {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			Intent i = new Intent(MainActivity.this, CaptureSignature.class);
			startActivityForResult(i, 0);
		}
	};

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		if (resultCode == 1) {
			Bitmap b = BitmapFactory.decodeByteArray(
					data.getByteArrayExtra("byteArray"), 0,
					data.getByteArrayExtra("byteArray").length);
			signImage.setImageBitmap(b);
		}
	}
}

  • Last but not the least, modify CaptureSignature Activity and return the result data in setResult(1, intent). In CaptureSignature Activity class you have to create an inner class which extends view and draw canvas using paint. The complete code of CaptureSignature Activity class is given below.

CaptureSignature.java

 

package com.example.signaturecapture;

import java.io.ByteArrayOutputStream;

import android.app.Activity;
import android.content.Context;
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.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class CaptureSignature extends Activity {
	signature mSignature;
	Paint paint;
	LinearLayout mContent;
	Button clear, save;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.capturesignature);

		save = (Button) findViewById(R.id.save);
		save.setEnabled(false);
		clear = (Button) findViewById(R.id.clear);
		mContent = (LinearLayout) findViewById(R.id.mysignature);

		mSignature = new signature(this, null);
		mContent.addView(mSignature);

		save.setOnClickListener(onButtonClick);
		clear.setOnClickListener(onButtonClick);
	}

	Button.OnClickListener onButtonClick = new Button.OnClickListener() {
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if (v == clear) {
				mSignature.clear();
			} else if (v == save) {
				mSignature.save();
			}
		}
	};

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

		float lastTouchX;
		float lastTouchY;
		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 clear() {
			path.reset();
			invalidate();
			save.setEnabled(false);
		}

		public void save() {
			Bitmap returnedBitmap = Bitmap.createBitmap(mContent.getWidth(),
					mContent.getHeight(), Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(returnedBitmap);
			Drawable bgDrawable = mContent.getBackground();
			if (bgDrawable != null)
				bgDrawable.draw(canvas);
			else
				canvas.drawColor(Color.WHITE);
			mContent.draw(canvas);

			ByteArrayOutputStream bs = new ByteArrayOutputStream();
			returnedBitmap.compress(Bitmap.CompressFormat.PNG, 50, bs);
			Intent intent = new Intent();
			intent.putExtra("byteArray", bs.toByteArray());
			setResult(1, intent);
			finish();
		}

		@Override
		protected void onDraw(Canvas canvas) {
			// TODO Auto-generated method stub
			canvas.drawPath(path, paint);
		}

		@Override
		public boolean onTouchEvent(MotionEvent event) {
			float eventX = event.getX();
			float eventY = event.getY();
			save.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);
					path.lineTo(historicalX, historicalY);
				}
				path.lineTo(eventX, eventY);
				break;
			}

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

 

 

 

Arpit Sharma

[email protected]

http://oodlestechnologies.com/

About Author

Author Image
Arpit Sharma

Arpit has been developing Android and iPhone applications for a while now and is expert in mobile application development . He excels in developing mobile applications with location based intelligence. Arpit loves Modelling as a hobby.

Request for Proposal

Name is required

Comment is required

Sending message..