Android:手指签名并出去掉周围的空白区域

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();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值