赞
踩
应用场景:
1.以前去银行办理业务都得去柜台,填N张表格,写N多个签名。随着智能机的普及、移动终端app的使用场景越来越广泛。手机银行app也给越来越多的人办理银行业务提供便捷,妈妈再也不用但是我们去银行排队浪费时间了。然而,有的业务该走的流程必须得走,所以电子签名的需求也就凸显出来。
2.小孩的作业
3.微信里面的涂鸦功能
sdk的封装东西
1.so库
2.jar
3.assert目录存放资源文件
客户端实现功能
1.可以保存,生成图片
2.可以取消
3.可以清除
4.生成签名图片 把view转成bitmap
5.图片压缩
流程
1.客户端生成加密串
2.通过接口得到加密串解密,这个时候回调用国家ca认证,有法律效应
3.把得到的信息图片和模板生成pdf文件
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SignatureView, 0, 0);
// Configurable parameters
try {
mMinWidth = a.getDimensionPixelSize(R.styleable.SignatureView_minWidth, convertDpToPx(3));
mMaxWidth = a.getDimensionPixelSize(R.styleable.SignatureView_maxWidth, convertDpToPx(7));
mVelocityFilterWeight = a.getFloat(R.styleable.SignatureView_velocityFilterWeight, 0.9f);
mPaint.setColor(a.getColor(R.styleable.SignatureView_penColor, Color.BLACK));
} finally {
a.recycle();
}
// Fixed parameters
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
// Dirty rectangle to update only the changed portion of the view
mDirtyRect = new RectF();
clear();
}
/**
* Set the pen color from a given resource. If the resource is not found,
* {@link android.graphics.Color#BLACK} is assumed.
*
* @param colorRes
* the color resource.
*/
public void setPenColorRes(int colorRes) {
try {
setPenColor(getResources().getColor(colorRes));
} catch (Resources.NotFoundException ex) {
setPenColor(getResources().getColor(Color.BLACK));
}
}
/**
* Set the pen color from a given color.
*
* @param color
* the color.
*/
public void setPenColor(int color) {
mPaint.setColor(color);
}
/**
* Set the minimum width of the stroke in pixel.
*
* @param minWidth
* the width in dp.
*/
public void setMinWidth(float minWidth) {
mMinWidth = convertDpToPx(minWidth);
}
/**
* Set the maximum width of the stroke in pixel.
*
* @param maxWidth
* the width in dp.
*/
public void setMaxWidth(float maxWidth) {
mMaxWidth = convertDpToPx(maxWidth);
}
/**
* Set the velocity filter weight.
*
* @param velocityFilterWeight
* the weight.
*/
public void setVelocityFilterWeight(float velocityFilterWeight) {
mVelocityFilterWeight = velocityFilterWeight;
}
public void clear() {
mPoints = new ArrayList<TimedPoint>();
mLastVelocity = 0;
mLastWidth = (mMinWidth + mMaxWidth) / 2;
mPath.reset();
if (mSignatureBitmap != null) {
mSignatureBitmap = null;
ensureSignatureBitmap();
}
setIsEmpty(true);
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled())
return false;
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
mPoints.clear();
mPath.moveTo(eventX, eventY);
mLastTouchX = eventX;
mLastTouchY = eventY;
addPoint(new TimedPoint(eventX, eventY));
case MotionEvent.ACTION_MOVE:
resetDirtyRect(eventX, eventY);
addPoint(new TimedPoint(eventX, eventY));
break;
case MotionEvent.ACTION_UP:
resetDirtyRect(eventX, eventY);
addPoint(new TimedPoint(eventX, eventY));
getParent().requestDisallowInterceptTouchEvent(true);
setIsEmpty(false);
break;
default:
return false;
}
// invalidate();
invalidate((int) (mDirtyRect.left - mMaxWidth), (int) (mDirtyRect.top - mMaxWidth),
(int) (mDirtyRect.right + mMaxWidth), (int) (mDirtyRect.bottom + mMaxWidth));
return true;
}
@Override
protected void onDraw(Canvas canvas) {
if (mSignatureBitmap != null) {
canvas.drawBitmap(mSignatureBitmap, 0, 0, mPaint);
}
}
public void setOnSignedListener(OnSignedListener listener) {
mOnSignedListener = listener;
}
public boolean isEmpty() {
return mIsEmpty;
}
public Bitmap getSignatureBitmap() {
Bitmap originalBitmap = getTransparentSignatureBitmap();
Bitmap whiteBgBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(whiteBgBitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
return whiteBgBitmap;
}
public void setSignatureBitmap(Bitmap signature) {
clear();
ensureSignatureBitmap();
RectF tempSrc = new RectF();
RectF tempDst = new RectF();
int dWidth = signature.getWidth();
int dHeight = signature.getHeight();
int vWidth = getWidth();
int vHeight = getHeight();
// Generate the required transform.
tempSrc.set(0, 0, dWidth, dHeight);
tempDst.set(0, 0, vWidth, vHeight);
Matrix drawMatrix = new Matrix();
drawMatrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER);
Canvas canvas = new Canvas(mSignatureBitmap);
canvas.drawBitmap(signature, drawMatrix, null);
setIsEmpty(false);
invalidate();
}
public Bitmap getTransparentSignatureBitmap() {
ensureSignatureBitmap();
return mSignatureBitmap;
}
public Bitmap getTransparentSignatureBitmap(boolean trimBlankSpace) {
if (!trimBlankSpace) {
return getTransparentSignatureBitmap();
}
ensureSignatureBitmap();
int imgHeight = mSignatureBitmap.getHeight();
int imgWidth = mSignatureBitmap.getWidth();
int backgroundColor = Color.TRANSPARENT;
int xMin = Integer.MAX_VALUE, xMax = Integer.MIN_VALUE, yMin = Integer.MAX_VALUE, yMax = Integer.MIN_VALUE;
boolean foundPixel = false;
// Find xMin
for (int x = 0; x < imgWidth; x++) {
boolean stop = false;
for (int y = 0; y < imgHeight; y++) {
if (mSignatureBitmap.getPixel(x, y) != backgroundColor) {
xMin = x;
stop = true;
foundPixel = true;
break;
}
}
if (stop)
break;
}
// Image is empty...
if (!foundPixel)
return null;
// Find yMin
for (int y = 0; y < imgHeight; y++) {
boolean stop = false;
for (int x = xMin; x < imgWidth; x++) {
if (mSignatureBitmap.getPixel(x, y) != backgroundColor) {
yMin = y;
stop = true;
break;
}
}
if (stop)
break;
}
// Find xMax
for (int x = imgWidth - 1; x >= xMin; x--) {
boolean stop = false;
for (int y = yMin; y < imgHeight; y++) {
if (mSignatureBitmap.getPixel(x, y) != backgroundColor) {
xMax = x;
stop = true;
break;
}
}
if (stop)
break;
}
// Find yMax
for (int y = imgHeight - 1; y >= yMin; y--) {
boolean stop = false;
for (int x = xMin; x <= xMax; x++) {
if (mSignatureBitmap.getPixel(x, y) != backgroundColor) {
yMax = y;
stop = true;
break;
}
}
if (stop)
break;
}
return Bitmap.createBitmap(mSignatureBitmap, xMin, yMin, xMax - xMin, yMax - yMin);
}
private void addPoint(TimedPoint newPoint) {
mPoints.add(newPoint);
if (mPoints.size() > 2) {
// To reduce the initial lag make it work with 3 mPoints
// by copying the first point to the beginning.
if (mPoints.size() == 3)
mPoints.add(0, mPoints.get(0));
ControlTimedPoints tmp = calculateCurveControlPoints(mPoints.get(0), mPoints.get(1), mPoints.get(2));
TimedPoint c2 = tmp.c2;
tmp = calculateCurveControlPoints(mPoints.get(1), mPoints.get(2), mPoints.get(3));
TimedPoint c3 = tmp.c1;
Bezier curve = new Bezier(mPoints.get(1), c2, c3, mPoints.get(2));
TimedPoint startPoint = curve.startPoint;
TimedPoint endPoint = curve.endPoint;
float velocity = endPoint.velocityFrom(startPoint);
velocity = Float.isNaN(velocity) ? 0.0f : velocity;
velocity = mVelocityFilterWeight * velocity + (1 - mVelocityFilterWeight) * mLastVelocity;
// The new width is a function of the velocity. Higher velocities
// correspond to thinner strokes.
float newWidth = strokeWidth(velocity);
// The Bezier's width starts out as last curve's final width, and
// gradually changes to the stroke width just calculated. The new
// width calculation is based on the velocity between the Bezier's
// start and end mPoints.
addBezier(curve, mLastWidth, newWidth);
mLastVelocity = velocity;
mLastWidth = newWidth;
// Remove the first element from the list,
// so that we always have no more than 4 mPoints in mPoints array.
mPoints.remove(0);
}
}
private void addBezier(Bezier curve, float startWidth, float endWidth) {
ensureSignatureBitmap();
float originalWidth = mPaint.getStrokeWidth();
float widthDelta = endWidth - startWidth;
float drawSteps = (float) Math.floor(curve.length());
for (int i = 0; i < drawSteps; i++) {
// Calculate the Bezier (x, y) coordinate for this step.
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 * curve.startPoint.x;
x += 3 * uu * t * curve.control1.x;
x += 3 * u * tt * curve.control2.x;
x += ttt * curve.endPoint.x;
float y = uuu * curve.startPoint.y;
y += 3 * uu * t * curve.control1.y;
y += 3 * u * tt * curve.control2.y;
y += ttt * curve.endPoint.y;
// Set the incremental stroke width and draw.
mPaint.setStrokeWidth(startWidth + ttt * widthDelta);
mSignatureBitmapCanvas.drawPoint(x, y, mPaint);
expandDirtyRect(x, y);
}
mPaint.setStrokeWidth(originalWidth);
}
- * view转bitmap
- */
- public Bitmap viewConversionBitmap(View v) {
- int w = v.getWidth();
- int h = v.getHeight();
-
- Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bmp);
-
- c.drawColor(Color.WHITE);
- /** 如果不设置canvas画布为白色,则生成透明 */
-
- v.layout(0, 0, w, h);
- v.draw(c);
-
- return bmp;
- }
下载地址如下:
https://github.com/gcacace/android-signaturepad
总结:
1.电子签名模糊的原理?
生成的图片被缩放了
2.电子签名有锯齿的问题?
因为没有用贝塞尔曲线
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。