最近做了电子签名的需求,其实就是绘制图片,下面给出所做的样式
自定义view,采用画笔绘制一张图片,保存到本地。接下来说一下主要的方法有清除,保存,获取路径等。
/**
* 清空签名
*/
public void clear() {
if (mCanvas != null) {
isTouched = false;
mPaint.setColor(mPenColor);
mCanvas.drawColor(mBackColor, PorterDuff.Mode.CLEAR);
mPaint.setColor(mPenColor);
invalidate();
}
}
/**
* 保存图片
* @param path 保存的地址
* @param clearBlank 是否清除空白区域
* @param blank 空白区域留空距离
*/
public void save(String path, boolean clearBlank, int blank) throws IOException {
if (TextUtils.isEmpty(path)) {
return;
}
mSavePath = path;
Bitmap bitmap = cacheBitmap;
if (clearBlank) {
bitmap = clearBlank(bitmap, blank);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
byte[] buffer = bos.toByteArray();
if (buffer != null) {
File file = new File(path);
if (file.exists()) {
file.delete();
}
OutputStream os = new FileOutputStream(file);
os.write(buffer);
os.close();
bos.close();
}
}
/**
* 获取Bitmap缓存
*/
public Bitmap getBitmap() {
setDrawingCacheEnabled(true);
buildDrawingCache();
Bitmap bitmap = getDrawingCache();
setDrawingCacheEnabled(false);
return bitmap;
}
/**
* 获取保存路径
*/
public String getSavePath() {
return mSavePath;
}
/**
* 逐行扫描,清除边界空白
*/
private Bitmap clearBlank(Bitmap bmp, int blank) {
int height = bmp.getHeight();
int width = bmp.getWidth();
int top = 0, left = 0, right = 0, bottom = 0;
int[] pixs = new int[width];
boolean isStop;
//扫描上边距不等于背景颜色的第一个点
for (int i = 0; i < height; i++) {
bmp.getPixels(pixs, 0, width, 0, i, width, 1);
isStop = false;
for (int pix :
pixs) {
if (pix != mBackColor) {
top = i;
isStop = true;
break;
}
}
if (isStop) {
break;
}
}
//扫描下边距不等于背景颜色的第一个点
for (int i = height - 1; i >= 0; i--) {
bmp.getPixels(pixs, 0, width, 0, i, width, 1);
isStop = false;
for (int pix :
pixs) {
if (pix != mBackColor) {
bottom = i;
isStop = true;
break;
}
}
if (isStop) {
break;
}
}
pixs = new int[height];
//扫描左边距不等于背景颜色的第一个点
for (int x = 0; x < width; x++) {
bmp.getPixels(pixs, 0, 1, x, 0, 1, height);
isStop = false;
for (int pix : pixs) {
if (pix != mBackColor) {
left = x;
isStop = true;
break;
}
}
if (isStop) {
break;
}
}
//扫描右边距不等于背景颜色的第一个点
for (int x = width - 1; x > 0; x--) {
bmp.getPixels(pixs, 0, 1, x, 0, 1, height);
isStop = false;
for (int pix : pixs) {
if (pix != mBackColor) {
right = x;
isStop = true;
break;
}
}
if (isStop) {
break;
}
}
if (blank < 0) {
blank = 0;
}
//计算加上保留空白距离之后的图像大小
left = left - blank > 0 ? left - blank : 0;
top = top - blank > 0 ? top - blank : 0;
right = right + blank > width - 1 ? width - 1 : right + blank;
bottom = bottom + blank > height - 1 ? height - 1 : bottom + blank;
return Bitmap.createBitmap(bmp, left, top, right - left, bottom - top);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
cacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(cacheBitmap);
mCanvas.drawColor(mBackColor);
isTouched = false;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(cacheBitmap, 0, 0, mPaint);
canvas.drawPath(mPath, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPenX = event.getX();
mPenY = event.getY();
mPath.moveTo(mPenX, mPenY);
return true;
case MotionEvent.ACTION_MOVE:
isTouched = true;
float x = event.getX();
float y = event.getY();
float preX = mPenX;
float preY = mPenY;
float dx = Math.abs(x - preX);
float dy = Math.abs(y - preY);
if (dx >= 3 || dy >= 3) {
float cx = (x + preX) / 2;
float cy = (y + preY) / 2;
mPath.quadTo(preX, preY, cx, cy);
mPenX = x;
mPenY = y;
}
invalidate();
break;
case MotionEvent.ACTION_UP:
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
break;
default:
break;
}
return super.onTouchEvent(event);
}
完整的demo请下载 https://download.csdn.net/download/lou_liang/12043935,希望对有需要的同学提供帮助。