首页 > 其他分享 >保存手写签名

保存手写签名

时间:2022-12-16 21:08:17浏览次数:37  
标签:layout 保存 id public 签名 new import 手写 android

Android 提供了很多丰富、实用而且很有特色的功能。比如,语音识别、手写签名等等。本篇就为你介绍如何在android上进行个性化的手写签名。

首先大致说说需求:这是一个追求时尚、张扬个性的时代,我们希望在签名的地方,签名的是自己手写出来的很有个性的艺术字,而非根据手势识别出来的标准字体。

设计思路如下,在画板上进行签名(其实就是绘制图片),完成后保存为图片。然后将图片按照一定的比率进行缩放并显示在指定的位置。

这里给出一个实例,实例只是一个简单的例子,如有需要可以进行必要的扩展。这里我们需要一个Listener、一个Dialog、一个Activity这个三个java类。两个layout XML文件。

Listener很简单,主要是对手写板对话框的一个监听。

1


2


3


4


5

​​public interface DialogListener {​​





​​public void refreshActivity(Object object);​​





​​}​​


接着是画板的Dialog

1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75


76


77


78


79


80


81


82


83


84


85


86


87


88


89


90


91


92


93


94


95


96


97


98


99


100


101


102


103


104


105


106


107


108


109


110


111


112


113


114


115


116


117


118


119


120


121


122


123


124


125


126


127


128


129


130


131


132


133


134


135


136


137


138


139


140


141


142


143


144


145


146


147


148


149


150


151


152


153


154


155


156


157


158


159


160


161


162


163


164


165


166


167


168


169


170


171


172


173


174


175


176


177


178


179


180


181


182


183


184


185


186


187


188


189


190


191


192


193


194


195


196


197


198


199


200


201


202


203

​​package cn.handwriting;​​





​​import android.app.Dialog;​​


​​import android.content.Context;​​


​​import android.graphics.Bitmap;​​


​​import android.graphics.Bitmap.Config;​​


​​import android.graphics.Canvas;​​


​​import android.graphics.Color;​​


​​import android.graphics.Paint;​​


​​import android.graphics.Path;​​


​​import android.os.Bundle;​​


​​import android.view.MotionEvent;​​


​​import android.view.View;​​


​​import android.view.Window;​​


​​import android.view.WindowManager.LayoutParams;​​


​​import android.widget.Button;​​


​​import android.widget.FrameLayout;​​








​​public class WritePadDialog extends Dialog {​​





​​Context context;​​


​​LayoutParams p ;​​


​​DialogListener dialogListener;​​





​​public WritePadDialog(Context context,DialogListener dialogListener) {​​


​​super​​ ​​(context);​​


​​this​​ ​​.context = context;​​


​​this​​ ​​.dialogListener = dialogListener;​​


​​}​​





​​static final int BACKGROUND_COLOR = Color.WHITE;​​





​​static final int BRUSH_COLOR = Color.BLACK;​​





​​PaintView mView;​​





​​/** The index of the current color to use. */​​


​​int mColorIndex;​​





​​@Override​​


​​protected void onCreate(Bundle savedInstanceState) {​​


​​super​​ ​​.onCreate(savedInstanceState);​​


​​requestWindowFeature(Window.FEATURE_NO_TITLE);​​


​​requestWindowFeature(Window.FEATURE_PROGRESS);​​


​​setContentView(R.layout.write_pad);​​





​​p = getWindow().getAttributes(); ​​ ​​//获取对话框当前的参数值 ​​


​​p.height = 320;​​ ​​//(int) (d.getHeight() * 0.4); //高度设置为屏幕的0.4 ​​


​​p.width = 480;​​ ​​//(int) (d.getWidth() * 0.6); //宽度设置为屏幕的0.6 ​​


​​getWindow().setAttributes(p); ​​ ​​//设置生效​​








​​mView = ​​ ​​new​​ ​​ PaintView(context);​​


​​FrameLayout frameLayout = (FrameLayout) findViewById(R.id.tablet_view);​​


​​frameLayout.addView(mView);​​


​​mView.requestFocus();​​


​​Button btnClear = (Button) findViewById(R.id.tablet_clear);​​


​​btnClear.setOnClickListener(​​ ​​new​​ ​​ View.OnClickListener() {​​





​​@Override​​


​​public void onClick(View v) {​​


​​mView.clear();​​


​​}​​


​​});​​





​​Button btnOk = (Button) findViewById(R.id.tablet_ok);​​


​​btnOk.setOnClickListener(​​ ​​new​​ ​​ View.OnClickListener() {​​





​​@Override​​


​​public void onClick(View v) {​​


​​try​​ ​​ {​​


​​dialogListener.refreshActivity(mView.getCachebBitmap());​​


​​WritePadDialog.​​ ​​this​​ ​​.dismiss();​​


​​} ​​ ​​catch​​ ​​ (Exception e) {​​


​​e.printStackTrace();​​


​​}​​


​​}​​


​​});​​





​​Button btnCancel = (Button)findViewById(R.id.tablet_cancel);​​


​​btnCancel.setOnClickListener(​​ ​​new​​ ​​ View.OnClickListener() {​​





​​@Override​​


​​public void onClick(View v) {​​


​​cancel();​​


​​}​​


​​});​​


​​}​​








​​/**​​


​​* This view implements the drawing canvas.​​


​​* ​​


​​* It handles all of the input events and drawing functions.​​


​​*/​​


​​class PaintView extends View {​​


​​private Paint paint;​​


​​private Canvas cacheCanvas;​​


​​private Bitmap cachebBitmap;​​


​​private Path path;​​





​​public Bitmap getCachebBitmap() {​​


​​return​​ ​​ cachebBitmap;​​


​​}​​





​​public PaintView(Context context) {​​


​​super​​ ​​(context); ​​


​​init(); ​​


​​}​​





​​private void init(){​​


​​paint = ​​ ​​new​​ ​​ Paint();​​


​​paint.setAntiAlias(​​ ​​true​​ ​​);​​


​​paint.setStrokeWidth(3);​​


​​paint.setStyle(Paint.Style.STROKE);​​


​​paint.setColor(Color.BLACK); ​​


​​path = ​​ ​​new​​ ​​ Path();​​


​​cachebBitmap = Bitmap.createBitmap(p.width, (int)(p.height*0.8), Config.ARGB_8888); ​​


​​cacheCanvas = ​​ ​​new​​ ​​ Canvas(cachebBitmap);​​


​​cacheCanvas.drawColor(Color.WHITE);​​


​​}​​


​​public void clear() {​​


​​if​​ ​​ (cacheCanvas != ​​ ​​null​​ ​​) {​​





​​paint.setColor(BACKGROUND_COLOR);​​


​​cacheCanvas.drawPaint(paint);​​


​​paint.setColor(Color.BLACK);​​


​​cacheCanvas.drawColor(Color.WHITE);​​


​​invalidate(); ​​


​​}​​


​​}​​











​​@Override​​


​​protected void onDraw(Canvas canvas) {​​


​​// canvas.drawColor(BRUSH_COLOR);​​


​​canvas.drawBitmap(cachebBitmap, 0, 0, ​​ ​​null​​ ​​);​​


​​canvas.drawPath(path, paint);​​


​​}​​





​​@Override​​


​​protected void onSizeChanged(int w, int h, int oldw, int oldh) {​​





​​int curW = cachebBitmap != ​​ ​​null​​ ​​ ? cachebBitmap.getWidth() : 0;​​


​​int curH = cachebBitmap != ​​ ​​null​​ ​​ ? cachebBitmap.getHeight() : 0;​​


​​if​​ ​​ (curW >= w && curH >= h) {​​


​​return​​ ​​;​​


​​}​​





​​if​​ ​​ (curW < w)​​


​​curW = w;​​


​​if​​ ​​ (curH < h)​​


​​curH = h;​​





​​Bitmap newBitmap = Bitmap.createBitmap(curW, curH, Bitmap.Config.ARGB_8888);​​


​​Canvas newCanvas = ​​ ​​new​​ ​​ Canvas();​​


​​newCanvas.setBitmap(newBitmap);​​


​​if​​ ​​ (cachebBitmap != ​​ ​​null​​ ​​) {​​


​​newCanvas.drawBitmap(cachebBitmap, 0, 0, ​​ ​​null​​ ​​);​​


​​}​​


​​cachebBitmap = newBitmap;​​


​​cacheCanvas = newCanvas;​​


​​}​​





​​private float cur_x, cur_y;​​





​​@Override​​


​​public boolean onTouchEvent(MotionEvent event) {​​





​​float x = event.getX();​​


​​float y = event.getY();​​





​​switch​​ ​​ (event.getAction()) {​​


​​case​​ ​​ MotionEvent.ACTION_DOWN: {​​


​​cur_x = x;​​


​​cur_y = y;​​


​​path.moveTo(cur_x, cur_y);​​


​​break​​ ​​;​​


​​}​​





​​case​​ ​​ MotionEvent.ACTION_MOVE: {​​


​​path.quadTo(cur_x, cur_y, x, y);​​


​​cur_x = x;​​


​​cur_y = y;​​


​​break​​ ​​;​​


​​}​​





​​case​​ ​​ MotionEvent.ACTION_UP: {​​


​​cacheCanvas.drawPath(path, paint);​​


​​path.reset();​​


​​break​​ ​​;​​


​​}​​


​​}​​





​​invalidate();​​





​​return​​ ​​ true​​ ​​;​​


​​}​​


​​}​​





​​}​​


Activity是程序的入口,这个必不可少。

1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75


76


77


78


79


80


81


82


83


84


85


86


87


88


89

​​package cn.handwriting;​​





​​import java.io.ByteArrayOutputStream;​​


​​import java.io.File;​​


​​import java.io.FileOutputStream;​​


​​import java.io.IOException;​​


​​import android.app.Activity;​​


​​import android.graphics.Bitmap;​​


​​import android.os.Bundle;​​


​​import android.os.Environment;​​


​​import android.view.View;​​


​​import android.view.View.OnClickListener;​​


​​import android.widget.ImageView;​​


​​import android.widget.TextView;​​





​​public class HandwritingActivity extends Activity {​​


​​/** Called when the activity is first created. */​​





​​private Bitmap mSignBitmap;​​


​​private String signPath;​​


​​private ImageView ivSign;​​


​​private TextView tvSign;​​


​​@Override​​


​​public void onCreate(Bundle savedInstanceState) {​​


​​super​​ ​​.onCreate(savedInstanceState);​​


​​setContentView(R.layout.main);​​


​​setTitle(​​ ​​"欢迎使用手写签名"​​ ​​);​​


​​ivSign =(ImageView)findViewById(R.id.iv_sign);​​


​​tvSign = (TextView)findViewById(R.id.tv_sign); ​​





​​ivSign.setOnClickListener(signListener);​​


​​tvSign.setOnClickListener(signListener);​​


​​}​​








​​private OnClickListener signListener = ​​ ​​new​​ ​​ View.OnClickListener() {​​





​​@Override​​


​​public void onClick(View v) {​​


​​WritePadDialog writeTabletDialog = ​​ ​​new​​ ​​ WritePadDialog(​​


​​HandwritingActivity.​​ ​​this​​ ​​, ​​ ​​new​​ ​​ DialogListener() {​​


​​@Override​​


​​public void refreshActivity(Object object) { ​​





​​mSignBitmap = (Bitmap) object;​​


​​signPath = createFile();​​


​​/*BitmapFactory.Options options = new BitmapFactory.Options();​​


​​options.inSampleSize = 15;​​


​​options.inTempStorage = new byte[5 * 1024];​​


​​Bitmap zoombm = BitmapFactory.decodeFile(signPath, options);*/​​


​​ivSign.setImageBitmap(mSignBitmap);​​


​​tvSign.setVisibility(View.GONE);​​


​​}​​


​​});​​


​​writeTabletDialog.show();​​


​​}​​


​​};​​





​​/**​​


​​* 创建手写签名文件​​


​​* ​​


​​* @return​​


​​*/​​


​​private String createFile() {​​


​​ByteArrayOutputStream baos = ​​ ​​null​​ ​​;​​


​​String _path = ​​ ​​null​​ ​​;​​


​​try​​ ​​ {​​


​​String sign_dir = Environment.getExternalStorageDirectory() + File.separator; ​​


​​_path = sign_dir + System.currentTimeMillis() + ​​ ​​".jpg"​​ ​​;​​


​​baos = ​​ ​​new​​ ​​ ByteArrayOutputStream();​​


​​mSignBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);​​


​​byte[] photoBytes = baos.toByteArray();​​


​​if​​ ​​ (photoBytes != ​​ ​​null​​ ​​) {​​


​​new​​ ​​ FileOutputStream(​​ ​​new​​ ​​ File(_path)).write(photoBytes);​​


​​}​​





​​} ​​ ​​catch​​ ​​ (IOException e) {​​


​​e.printStackTrace();​​


​​} finally {​​


​​try​​ ​​ {​​


​​if​​ ​​ (baos != ​​ ​​null​​ ​​)​​


​​baos.close();​​


​​} ​​ ​​catch​​ ​​ (IOException e) {​​


​​e.printStackTrace();​​


​​}​​


​​}​​


​​return​​ ​​ _path;​​


​​}​​


​​}​​


对应的两个layout文件
main.xml

1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24

​​<?xml version=​​ ​​"1.0"​​ ​​ encoding=​​ ​​"utf-8"​​ ​​?>​​


​​<LinearLayout xmlns:android=​​ ​​"http://schemas.android.com/apk/res/android"​​


​​android:layout_width=​​ ​​"fill_parent"​​


​​android:layout_height=​​ ​​"fill_parent"​​


​​android:orientation=​​ ​​"vertical"​​ ​​ >​​





​​<ImageView ​​


​​android:id=​​ ​​"@+id/iv_sign"​​


​​android:layout_marginTop=​​ ​​"50dp"​​


​​android:layout_width=​​ ​​"wrap_content"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:layout_gravity=​​ ​​"center"​​


​​/>​​





​​<TextView​​


​​android:id=​​ ​​"@+id/tv_sign"​​


​​android:layout_marginTop=​​ ​​"50dp"​​


​​android:layout_below=​​ ​​"@id/iv_sign"​​


​​android:layout_width=​​ ​​"wrap_content"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:layout_gravity=​​ ​​"center"​​


​​android:text=​​ ​​"点此签名"​​


​​/> ​​


​​</LinearLayout>​​


write_pad.xml

1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43

​​<LinearLayout xmlns:android=​​ ​​"http://schemas.android.com/apk/res/android"​​


​​xmlns:greendroid=​​ ​​"http://schemas.android.com/apk/res/com.cyrilmottier.android.gdcatalog"​​


​​android:layout_width=​​ ​​"fill_parent"​​


​​android:layout_height=​​ ​​"fill_parent"​​


​​android:orientation=​​ ​​"vertical"​​ ​​ >​​





​​<FrameLayout​​


​​android:id=​​ ​​"@+id/tablet_view"​​


​​android:layout_width=​​ ​​"fill_parent"​​


​​android:layout_height=​​ ​​"0dp"​​


​​android:layout_weight=​​ ​​"1"​​


​​android:background=​​ ​​"@color/white"​​ ​​>​​


​​</FrameLayout>​​





​​<LinearLayout​​


​​android:layout_width=​​ ​​"fill_parent"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:background=​​ ​​"@android:drawable/bottom_bar"​​


​​android:paddingTop=​​ ​​"4dp"​​ ​​ >​​





​​<Button​​


​​android:id=​​ ​​"@+id/tablet_ok"​​


​​android:layout_width=​​ ​​"0dp"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:layout_weight=​​ ​​"1"​​


​​android:text=​​ ​​"确定"​​ ​​ />​​





​​<Button​​


​​android:id=​​ ​​"@+id/tablet_clear"​​


​​android:layout_width=​​ ​​"0dp"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:layout_weight=​​ ​​"1"​​


​​android:text=​​ ​​"清除"​​ ​​ />​​





​​<Button​​


​​android:id=​​ ​​"@+id/tablet_cancel"​​


​​android:layout_width=​​ ​​"0dp"​​


​​android:layout_height=​​ ​​"wrap_content"​​


​​android:layout_weight=​​ ​​"1"​​


​​android:text=​​ ​​"取消"​​ ​​ />​​


​​</LinearLayout>​​





​​</LinearLayout>​​


这里还有个样式的设置,所以在values下添加了一个colors.xml文件。

标签:layout,保存,id,public,签名,new,import,手写,android
From: https://blog.51cto.com/u_13657808/5948377

相关文章