1.思路,自定义view,根据touch的位置,设置path,画path即可
2.把view保存成bitmap
3.便利bitmap的像素点,得到签字区域,
4.切割下bitmap。
第一:
package com.dxxx.livingtask_songjiang.signutil;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.facebook.stetho.Stetho;
/**
* Created by shibo on 2018/3/7.
*/
public class SignView extends View {
private Path path;
private Paint paint;
public SignView(Context context) {
super(context);
initView();
}
public SignView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public SignView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public SignView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initView();
}
private void initView() {
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.parseColor("#000000"));
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (path == null) {
} else {
// Log.e("开始绘制", "====");
canvas.drawPath(path, paint);
}
}
boolean canDraw;
//开始的点
float x;
float y;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (path == null) {
path = new Path();
}
x = event.getX();
y = event.getY();
path.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
Log.e("移动的两个数值", "=");
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void clearCanvas() {
path = null;
invalidate();
}
/**
* 判断签名区域是否有内容
*
* @return
*/
public boolean pathIsNull() {
if (path == null) {
return true;
} else {
return false;
}
}
}
第二:
使用DrawCach
view.setDrawingCacheEnabled(true);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
view.setDrawingCacheBackgroundColor(Color.WHITE);
view.buildDrawingCache();
Bitmap image = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
使用canvas
private Bitmap loadBitmapFromView(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;
}
第三:有两种方法
//根据X,Y获取这个点的色值
private void useGetPixel(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
List<PointBean> clum = new ArrayList<>();
boolean hadClumMin = false;
int clumMin = 0;
for (int i = 0; i < height; i++) {
boolean hadBlack = false;
for (int j = 0; j < width; j++) {
int color = bitmap.getPixel(j, i);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
int alpha = Color.alpha(color);
if (red == 0 && green == 0 && blue == 0 && alpha == 255) {
hadBlack = true;
if (hadClumMin) {
} else {
clumMin = i;
hadClumMin = true;
}
}
}
if (hadBlack) {
clum.add(new PointBean(i, true));
}
}
//开始计算最大值
int clumMax = 0;
for (PointBean pointBean : clum) {
if (pointBean.getIndex() > clumMax) {
clumMax = pointBean.getIndex();
}
}
//获取横向上的值
boolean hadRowMin = false;
int rowMin = 0;
List<PointBean> row = new ArrayList<>();
for (int i = 0; i < width; i++) {
boolean hadBlack = false;
for (int j = 0; j < height; j++) {
int color = bitmap.getPixel(i, j);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
int alpha = Color.alpha(color);
if (red == 0 && green == 0 && blue == 0 && alpha == 255) {
hadBlack = true;
if (hadRowMin) {
} else {
rowMin = i;
hadRowMin = true;
}
}
}
if (hadBlack) {
row.add(new PointBean(i, true));
}
}
int rowMax = 0;
for (PointBean pointBean : row) {
if (pointBean.getIndex() > rowMax) {
rowMax = pointBean.getIndex();
}
}
Log.e("四个数值1",rowMin+","+clumMin+","+rowMax +","+clumMax);
Log.e("四个数值",rowMin+","+clumMin+","+(rowMax - rowMin)+","+(clumMax - clumMin));
Bitmap mBitmap3 = Bitmap.createBitmap(bitmap, rowMin, clumMin, rowMax - rowMin, clumMax - clumMin);
saveBitmap(mBitmap3);
}
方法2.
//将整张图转换为二维像素点
private void useGetPixels(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
//getPixels()函数把一张图片,从指定的偏移位置(offset),指定的位置(x,y)截取指定的宽高(width,height ),把所得图像的每个像素颜色转为int值,存入pixels。
//获取像素集合,width的意思是一行有width个像素
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);//得到图片的所有像素
//Log.e("==", Arrays.toString(pixels));
boolean getClumStart = false;//竖直上的起始点
boolean getClumStop = false;//竖直上的结束点
int clumStart = 0;//竖直上开始的点
int clumStop = 0;//竖直上结束的点
List<PointBean> allPoint_Clum = new ArrayList<>();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width - 1; j++) {
// 分离三原色
int alpha = Color.alpha(pixels[i * width + j]);
int red = Color.red(pixels[i * width + j]);
int green = Color.green(pixels[i * width + j]);
int blue = Color.blue(pixels[i * width + j]);
//Log.e("色值",red+","+green+","+blue);
//这里是二值化化的判断,if里是白色,else里是黑色
if (red == 255 && green == 255 && blue == 255) {
//不能在这判断结束是因为如果笔画在中间位置,那么笔画左边的部分,下标不等于开始而且还是空白
} else {
if (red == 0 && green == 0 && blue == 0 && alpha == 255) {
// Log.e("新增的i", i + "");
PointBean pointBean = new PointBean();
pointBean.setIndex(i);
pointBean.setHadBlack(true);
allPoint_Clum.add(pointBean);
if (getClumStart) {
//已经找到开始点了
} else {
//开始点一定正确
getClumStart = true;
clumStart = i;
}
}
}
}
}
//有竖直方向上的开始值,遍历list,找到黑点最大的值,再加一就是结束的位置
int big = allPoint_Clum.get(0).getIndex();
Log.e("第一次的big", big + "");
for (int i = 0; i < allPoint_Clum.size(); i++) {
if (allPoint_Clum.get(i).getIndex() > big) {
big = allPoint_Clum.get(i).getIndex();
}
// Log.e("中间的big",big+"");
}
clumStop = big;
Log.e("竖直方向上的起始点是", clumStart + "," + clumStop + "原大小" + width + "," + height);
//再来取水平方向上的
//int[] pixels_row = new int[width * height];
// bitmap.getPixels(pixels_row, 0, width, 0, 0, width, height);//得到图片的所有像素
boolean getRowStart = false;//shu水平上的起始点
boolean getRowStop = false;//水平上的结束点
int RowStart = 0;//水平上开始的点
int RowStop = 0;//水平上结束的点
List<PointBean> allPoint_Row = new ArrayList<>();
for (int i = 0; i < width; i++) {
boolean hadBreak = false;
for (int j = 0; j < height - 1; j++) {
// 分离三原色
int alpha = Color.alpha(pixels[j * width + i]);
int red = Color.red(pixels[j * width + i]);
int green = Color.green(pixels[j * width + i]);
int blue = Color.blue(pixels[j * width + i]);
// Log.e("色值",red+","+green+","+blue);
//这里是二值化化的判断,if里是白色,else里是黑色
if (red == 255 && green == 255 && blue == 255) {
//不能在这判断结束是因为如果笔画在中间位置,那么笔画左边的部分,下标不等于开始而且还是空白
} else {
if (red == 0 && green == 0 && blue == 0 && alpha == 255) {
if (hadBreak) {
} else {
hadBreak = true;
PointBean pointBean = new PointBean();
pointBean.setIndex(i);
pointBean.setHadBlack(true);
allPoint_Row.add(pointBean);
if (getRowStart) {
//已经找到开始点了
} else {
//开始点一定正确
getRowStart = true;
RowStart = i;
//Log.e("shui水平上的额之", i + "");
}
}
} else {
}
}
}
}
//有竖直方向上的开始值,遍历list,找到黑点最大的值,再加一就是结束的位置
int big_row = allPoint_Row.get(0).getIndex();
for (int i = 0; i < allPoint_Row.size(); i++) {
if (allPoint_Row.get(i).getIndex() > big_row) {
big_row = allPoint_Row.get(i).getIndex();
}
}
RowStop = big_row + 1;
Log.e("水平方向上的起始点是", RowStart + "," + RowStop + "原大小" + width + "," + height);
//RowStop - RowStart
// bitmap.getPixels(pixels,0,width,0,0,width/2,height/2);
Bitmap bi = Bitmap.createBitmap(pixels, 0, width / 2, width / 2, height / 2, Bitmap.Config.ARGB_8888);
Bitmap mBitmap3 = Bitmap.createBitmap(bitmap, RowStart, clumStart, RowStop - RowStart, clumStop - clumStart);
saveBitmap(mBitmap3);
}
第四
private void saveBitmap(Bitmap bitmap1) {
FileOutputStream fos;
try {
File file = FileForIamgeUtil.createImageFile(getContext());
if (file == null) {
Toast.makeText(getContext(), "获取存储路径异常", Toast.LENGTH_SHORT).show();
return;
}
fos = new FileOutputStream(file);
bitmap1.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(getContext(), "保存成功", Toast.LENGTH_SHORT).show();
dismiss();
savaSuccess.success(Uri.fromFile(file));
} catch (Exception e) {
e.printStackTrace();
savaSuccess.fail(e.getMessage() + "==");
}
view.destroyDrawingCache();
}