自定义Android手写签名板组件,并进行手写区域裁剪,最终得到手写区域的图片(不是整个手写板区域)
使用方法:

/*** 初始化视图,将手写版添加到布局中*/private void initView() {mDrawView = new DrawView(this);LinearLayout layout;// layout中挂载的一个布局,用来加载手写板ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);mDrawView.setLayoutParams(layoutParams);layout.addView(mDrawView);}
/*** 将手写签名的图片保存到服务端* 1.进行90度逆时针旋转     * 2.将图片压缩处理成400x160尺寸* 3.将图片上传给服务端*/private void saveHandlerImage() {Bitmap bitmap = mDrawView.getResizeBitmap();if (bitmap == null) {showToast("请手写后再保存");return;}// 由于是竖屏,用户一般是横着写,因此需要在图片处理时进行逆时针旋转Bitmap bitmapRotate = BitmapUtil.rotateBitmap(bitmap, -90);}
package cn.org.bjca.sdk.core.v3.widget;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;public class DrawView extends View {private Context context;//X轴起点private float x;//Y轴起点private float y;//画笔private final Paint paint = new Paint();//路径private final Path path = new Path();//画布private Canvas canvas;//生成的图片private Bitmap bitmap;//画笔的宽度private int paintWidth = 6;//签名颜色private int paintColor = Color.BLACK;//背景颜色private int backgroundColor = Color.WHITE;//是否已经签名private boolean isTouched = false;float minX = -1;float minY = -1;float maxX = -1;float maxY = -1;Bitmap backBitmap;//签名开始与结束public interface Touch {void OnTouch(boolean isTouch);}private Touch touch;public DrawView(Context context) {super(context);init(context);}public DrawView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context) {this.context = context;//抗锯齿paint.setAntiAlias(true);//样式paint.setStyle(Paint.Style.STROKE);//线冒paint.setStrokeCap(Paint.Cap.ROUND);//画笔颜色paint.setColor(paintColor);//画笔宽度paint.setStrokeWidth(paintWidth);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//创建于view大小一致的bitmapbitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);bitmap.setHasAlpha(true);canvas = new Canvas(bitmap);isTouched = false;}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (touch != null) touch.OnTouch(true);switch (event.getAction()) {//手指按下case MotionEvent.ACTION_DOWN:touchDown(event);break;//手指移动case MotionEvent.ACTION_MOVE:if (touch != null) touch.OnTouch(false);touchMove(event);break;//手指抬起case MotionEvent.ACTION_UP:isTouched=true;canvas.drawPath(path, paint);path.reset();canvas.drawPoint(event.getX(),event.getY(),paint);this.checkEffectivePoint(event.getX(), event.getY());break;}// 更新绘制invalidate();return true;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画此次笔画之前的签名canvas.drawBitmap(bitmap, 0, 0, paint);// 通过画布绘制多点形成的图形canvas.drawPath(path, paint);}//手指按下的方法private void touchDown(MotionEvent event) {//重置绘制路径path.reset();float downX = event.getX();float downY = event.getY();x = downX;y = downY;//绘制起点path.moveTo(downX, downY);}//手指滑动的方法private void touchMove(MotionEvent event) {//当前的x,y坐标点final float moveX = event.getX();final float moveY = event.getY();//之前的x,y坐标点final float previousX = x;final float previousY = y;//获取绝对值final float dx = Math.abs(moveX - previousX);final float dy = Math.abs(moveY - previousY);if (dx >= 3 || dy >= 3) {float cX = (moveX + previousX) / 2;float cY = (moveY + previousY) / 2;path.quadTo(previousX, previousY, cX, cY);x = moveX;y = moveY;}this.checkEffectivePoint(x, y);}/*** 重新计算手写签名的有效区域** @param x* @param y*/public void checkEffectivePoint(float x, float y) {int mCanvasWidth = canvas.getWidth();int mCanvasHeight = canvas.getHeight();if (x >= 0 && x <= mCanvasWidth) {if (x - paintWidth < minX || minX == -1) {minX = x - paintWidth;if (minX < 0) {minX = 0;}}if (x + paintWidth > maxX || maxX == -1) {maxX = x + paintWidth;if (maxX > mCanvasWidth) {maxX = mCanvasWidth;}}}if (y >= 0 && y <= mCanvasHeight) {if (y - paintWidth < minY || minY == -1) {minY = y - paintWidth;if (minY < 0) {minY = 0;}}if (y + paintWidth > maxY || maxY == -1) {maxY = y + paintWidth;if (maxY > mCanvasHeight) {maxY = mCanvasHeight;}}}}/*** 设置画笔颜色** @param paintColor*/public void setPaintColor(int paintColor) {this.paintColor = paintColor;paint.setColor(paintColor);}/*** 设置画笔宽度** @param paintWidth*/public void setPaintWidth(int paintWidth) {this.paintWidth = paintWidth;paint.setStrokeWidth(paintWidth);}/*** 设置画板颜色** @param canvasColor*/public void setCanvasColor(int canvasColor) {this.backgroundColor = canvasColor;}public void setBackgroundImage(int imageId) {super.setBackgroundResource(imageId);}/*** 清除画板*/public void clear() {if (canvas != null) {isTouched = false;//更新画板paint.setColor(paintColor);paint.setStrokeWidth(paintWidth);canvas.drawColor(Color.parseColor("#00000000"), PorterDuff.Mode.CLEAR);invalidate();}}/*** 获取画板的Bitmap** @return*/public Bitmap getBitmap() {if (!isTouched) {return null;}setDrawingCacheEnabled(true);buildDrawingCache();setDrawingCacheEnabled(false);destroyDrawingCache();return bitmap;}/*** 获取根据手写区域截取后的图片** @return*/public Bitmap getResizeBitmap() {Bitmap bitmap = this.getBitmap();if (null == bitmap) {return null;}Log.e("TAG", String.format("minX= %s\tminY= %s\tmaxX= %s\tmaxY= %s\t", minX, minY, maxX, maxY));return Bitmap.createBitmap(bitmap, (int) minX, (int) minY,(int) maxX - (int) minX, (int) maxY - (int) minY);}}

Android实现手写板功能相关推荐

  1. android开发分享Android实现手写板功能

    笔画为一次down-move-up的集合撤销笔画并非一次path的动作撤销 应该也是一次down-move -up的撤销为了更好的笔画需要使用贝塞尔曲线来完成 手写板文件:url80.ctfile.c ...

  2. Android 实现闹钟功能

      原文地址:Android 实现闹钟功能作者:Android_Learners 一.手机闹钟主要用到了AlarmManager类,AlarmManager类提供了访问系统定时服务的途径,开发人员可以 ...

  3. android 添加附件功能,Android实现带附件的邮件发送功能

    本文实例讲解了基于基于jmail实现android邮件发送功能,分享给大家供大家参考,具体内容如下 在android上发送邮件方式: 第一种:借助gmail app客户端,缺点是必须使用gmail帐号 ...

  4. android倒计时功能,android实现倒计时功能(开始、暂停、0秒结束)

    本文实例为大家分享了android实现倒计时功能的具体代码,供大家参考,具体内容如下 [思路]:通过 timer 执行周期延时的任务,handler 中将计时信息更新,并在计时结束时结束 timer ...

  5. android p新功能_android 11今天发布这是新功能

    android p新功能 Google has just released the upgraded OS to select Pixel, OnePlus, and Xiaomi phones. A ...

  6. android 带清除功能的输入框控件

    今天,看到一个很好的自定义输入框控件,于是记录一下. 效果很好: 一,自定义一个类,名为ClearEditText package com.example.clearedittext;import a ...

  7. android 调用红外模块,Flutter调用Android模块的功能

    Flutter调用Android模块的功能,主要通过MethodChannel Flutter端 const MethodChannel _channel = const MethodChannel( ...

  8. android 最新功能介绍,Android Studio 常用功能介绍

    界面介绍 讲解1 这个界面,显示了我们使用 Android Studio时经常接触到的功能面板. Project 面板. 用于浏览项目文件. Project 面板会显示当前的所有的 module .  ...

  9. 集成Android免费语音合成功能(在线、离线、离在线融合),有这一篇文章就够了(离线)

    原址 集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(在线) 集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离在线融合)     ...

最新文章

  1. IOS UiView frame哪里来?
  2. Java中创建对象的几种方式
  3. Kubernetes初体验
  4. Sublime Text 2 快捷键用法大全
  5. Intel QuickAssist Technology and OpenSSL – Benchmarks and Setup Tips
  6. 近来接连换了U盘、剃须刀,京东服务确实好
  7. java Socket(TCP)编程小项目
  8. 读书笔记:《用户故事与敏捷方法》
  9. xlsx模块 前端_前端使用SheetJS的xlsx.js实现excel表格生成
  10. DCE/MS RPC旁窥
  11. ApplePay 支付开发
  12. 非root用户安装或升级CUDA和CUDNN版本
  13. 建筑CAD基础设计【1】
  14. 【历史上的今天】2 月 17 日:谷歌收购 Blogger;英伟达创始人出生;微软发布 Windows 2000
  15. 支付宝支付接口、支付宝订单查询接口 前端为APP
  16. VxRail升级软件/固件版本
  17. 蛟龙未遇,潜身于鱼虾之间;君子失时,拱手于小人之下。
  18. [Linux 学习] grub 引导文件
  19. 联邦平均算法(Federated Averaging Algorithm,FedAvg)
  20. 百度凤巢计划,中华英才网有点烦

热门文章

  1. java工程师报考费用_Java工程师的年薪是多少钱
  2. 《设计模式之禅》之六大设计原则
  3. 【企业信息化】第5集 免费开源ERP: Odoo 16 inventory仓库管理系统 现代化线上仓库管理软件
  4. 人间地狱服务器一直显示有人,人间地狱常见问题及解决方法_Hell Let Loose常见问题QA_游戏堡...
  5. 《Oracle编程自学与面试指南》17-03:多列子查询
  6. KDD Cup风力发电赛题详解-附baseline代码【时间序列相关赛题方案】
  7. 博客停更,已开公众号-《GIS杂谈》,可直接在微信搜索公众号名称关注,之后会在公众号持续更新相关知识,敬请关注,欢迎讨论~
  8. IP属地的功能是如何实现的呢,简单实现获取ip地址和IP属地。
  9. session共享的另外一篇博客.好文章
  10. 一杯睡前牛奶,会不会让年轻人的失眠有尽头?