自定義View實現手繪簽名並保存成圖片存入本地

由於上個星期公司要實現一個功能,是關於合同的,需要用戶簽名,由此引發書寫了這篇文章,此文設計的內容並不複雜,下面是梳理過程

自定義一個View監聽手勢動作,利用Path將手勢軌跡繪製到canvas。然後創建一個CacheCanvas,並設置一個Bitmap,在繪製的到canvas的同時並繪製到cacheCanvas上,以便將其取出,將bitmap存入本地

直接看代碼 SignatureView

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.io.*;

/**
 * @Author MarkYe
 * @Email [email protected]
 * @Date 2019-06-09
 * @Des 手繪簽名View
 */
public class SignatureView extends View {
    private Paint mPaint;
    private Path mPath;
    private Bitmap cacheBitmap;//用戶保存簽名的Bitmap
    private Canvas cacheCanvas;//用戶保存簽名的Canvas
    private float lift, right, top, bottom;

    public SignatureView(Context context) {
        this(context, null);
    }

    public SignatureView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        //初始化畫筆
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(10);
        mPath = new Path();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        cacheBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        cacheCanvas = new Canvas(cacheBitmap);
        //設置背景色爲透明
        cacheCanvas.drawColor(Color.TRANSPARENT);

    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //路徑起點
                mPath.moveTo(event.getX(), event.getY());

                if (lift == 0) {
                    lift = event.getX();
                }
                if (right == 0) {
                    lift = event.getX();
                }
                if (top == 0) {
                    top = event.getX();
                }
                if (bottom == 0) {
                    bottom = event.getX();
                }
                setVertexCoordinates(event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(event.getX(), event.getY());
                postInvalidate();
                setVertexCoordinates(event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_UP:
                //將簽名繪製到緩存畫布上
                cacheCanvas.drawPath(mPath, mPaint);
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //繪製簽名路徑
        canvas.drawPath(mPath, mPaint);
    }

    /**
     * 重置畫布
     */
    public void resetCanvas() {
        mPath.reset();
        invalidate();


        cacheBitmap = null;
        cacheCanvas = null;
        cacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        cacheCanvas = new Canvas(cacheBitmap);
        //設置背景色爲透明
        cacheCanvas.drawColor(Color.TRANSPARENT);
        lift = right = top = bottom = 0;

    }

    /**
     * 設置頂點座標
     */
    private void setVertexCoordinates(Float x, Float y) {
        if (lift > x)
            lift = x;
        if (right < x)
            right = x;
        if (top > y)
            top = y;
        if (bottom < y)
            bottom = y;
    }


    /**
     * 剪裁畫布把多餘的畫布去掉只保留簽名部分
     *
     * @param blank 邊距
     */
    private Bitmap cropCanvas(int blank) {
//        left, top, right - left, bottom - top
        Log.w("cropCanvas", "lift " + lift);
        Log.w("cropCanvas", "right " + right);
        Log.w("cropCanvas", "top " + top);
        Log.w("cropCanvas", "bottom " + bottom);
        try {
            return Bitmap.createBitmap(cacheBitmap, (int) lift - blank, (int) top - blank, (int) right + 2 * blank - (int) lift, (int) bottom + 2 * blank - (int) top);
        } catch (Exception e) {
            e.printStackTrace();
            return cacheBitmap;
        }
    }

    /**
     * 判斷有沒有簽名
     * @return true 有 反之沒有
     */
    public boolean isEmpty(){
      return   mPath.isEmpty();
    }

    /**
     * 保存簽名到本地
     *
     * @param path  保存路徑
     * @param blank 邊距
     */
    public void save(String path, int blank) {
        Bitmap mBitmap = cropCanvas(blank);
        File mFile = new File(path);
        try {
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(mFile));
            mBitmap.compress(Bitmap.CompressFormat.PNG, 100, bufferedOutputStream);
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

給大家看看效果圖吧,PS(懶得弄gif了,這是靜態圖)

在這裏插入圖片描述
由於功能比較少,沒有將源碼放到GitHub上,加如需使用直接copySignatureView的代碼就行了。
童鞋們下次再見!
ok. THE END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章