美文网首页
电子合同签名 自定义View

电子合同签名 自定义View

作者: 杰奎琳子 | 来源:发表于2020-07-07 12:14 被阅读0次

主要实现自定义View

public class GestureSignatureView extends View {

private static final String TAG = "GestureSignatureView";

    private Path mPath;//绘制路径

    private Paint mPaint;// 绘制画笔

    private Canvas mCanvas;//背景画布

    private Bitmap mMBitmap;//背景bitmap

    private boolean isTouchedSignature = false;//是否签名

    public GestureSignatureView(Context context) {

        this(context, null);

    }

    public GestureSignatureView(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }

    public GestureSignatureView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initPaint();

    }

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        Log.d(TAG, "onMeasure: 测量的宽高:" + getMeasuredWidth() + "-----------" + getMeasuredHeight());

    }

    @Override

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        super.onLayout(changed, left, top, right, bottom);

        mMBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

        mCanvas = new Canvas(mMBitmap);

        mCanvas.drawColor(Color.TRANSPARENT);

        mCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));

        isTouchedSignature = false;

    }

    private void initPaint() {

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mPaint.setColor(Color.BLACK);

        mPaint.setStrokeWidth(10.0f);

        mPaint.setStrokeCap(Paint.Cap.ROUND);

        mPaint.setStyle(Paint.Style.STROKE);

        mPaint.setStrokeJoin(Paint.Join.ROUND);

        mPaint.setDither(true);

        mPath = new Path();

    }

    @Override

    protected void onDraw(Canvas canvas) {

        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));

        canvas.drawBitmap(mMBitmap, 0, 0, mPaint);

        // 通过画布绘制多点形成的图形

        canvas.drawPath(mPath, mPaint);

    }

    private float[] downPoint = new float[2];

    private float[] previousPoint = new float[2];

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        downPoint[0] = event.getX();

        downPoint[1] = event.getY();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                previousPoint[0] = downPoint[0];

                previousPoint[1] = downPoint[1];

                mPath.moveTo(downPoint[0], downPoint[1]);

                break;

            case MotionEvent.ACTION_MOVE:

                float dX = Math.abs(downPoint[0] - previousPoint[0]);

                float dY = Math.abs(downPoint[1] - previousPoint[1]);

                // 两点之间的距离大于等于3时,生成贝塞尔绘制曲线

                if (dX >= 3 || dY >= 3) {

                    // 设置贝塞尔曲线的操作点为起点和终点的一半

                    float cX = (downPoint[0] + previousPoint[0]) / 2;

                    float cY = (downPoint[1] + previousPoint[1]) / 2;

                    // 二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点

                    mPath.quadTo(previousPoint[0], previousPoint[1], cX, cY);

                    // 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值

                    previousPoint[0] = downPoint[0];

                    previousPoint[1] = downPoint[1];

                }

//                float moveCurrentX = downPoint[0];

//                float moveCurrentY = downPoint[1];

//                mPath.quadTo(moveCurrentX, moveCurrentY, downPoint[0], downPoint[1]);

                break;

            case MotionEvent.ACTION_UP:

                mCanvas.drawPath(mPath, mPaint);

                mPath.reset();

                break;

        }

        invalidate();

        return true;

    }

    // 缩放

    public static Bitmap resizeImage(Bitmap bitmap, int width, int height) {

        int originWidth = bitmap.getWidth();

        int originHeight = bitmap.getHeight();

        float scaleWidth = ((float) width) / originWidth;

        float scaleHeight = ((float) height) / originHeight;

        Matrix matrix = new Matrix();

        matrix.postScale(scaleWidth, scaleHeight);

        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth,

                originHeight, matrix, true);

        return resizedBitmap;

    }

    public Bitmap getPaintBitmap() {

        return resizeImage(mMBitmap, 320, 480);

    }

    public void clear() {

        if (mCanvas != null) {

            isTouchedSignature = false;

            mPath.reset();

            mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

            invalidate();

        }

    }

    /**

    * 保存画板

    *

    * @param path 保存到路劲

    */

    public void save(String path) throws IOException {

        save(path, false, 0);

    }

    /**

    * 保存画板

    *

    * @param path      保存到路劲

    * @param clearBlank 是否清楚空白区域

    * @param blank      边缘空白区域

    */

    public void save(String path, boolean clearBlank, int blank) throws IOException {

        Bitmap bitmap = mMBitmap;

        //BitmapUtil.createScaledBitmapByHeight(srcBitmap, 300);//  压缩图片

        if (clearBlank) {

            bitmap = clearBlank(mMBitmap, blank);

        }

        Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(newBitmap);

        canvas.drawColor(Color.WHITE);

        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));

        canvas.drawBitmap(bitmap, 0, 0, null);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

        byte[] buffer = bos.toByteArray();

        if (buffer != null) {

            File file = new File(path);

            if (file.exists()) {

                file.delete();

            }

            OutputStream outputStream = new FileOutputStream(file);

            outputStream.write(buffer);

            outputStream.close();

            scanMediaFile(file);

        }

    }

    /**

    * 是否有签名

    *

    * @return

    */

    public boolean getTouched() {

        return isTouchedSignature;

    }

    /**

    * 逐行扫描 清楚边界空白。

    *

    * @param bp

    * @param blank 边距留多少个像素

    * @return

    */

    private Bitmap clearBlank(Bitmap bp, int blank) {

        int HEIGHT = bp.getHeight();

        int WIDTH = bp.getWidth();

        int top = 0, left = 0, right = 0, bottom = 0;

        int[] pixs = new int[WIDTH];

        boolean isStop;

        for (int y = 0; y < HEIGHT; y++) {

            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1);

            isStop = false;

            for (int pix : pixs) {

                if (pix != Color.TRANSPARENT) {

                    top = y;

                    isStop = true;

                    break;

                }

            }

            if (isStop) {

                break;

            }

        }

        for (int y = HEIGHT - 1; y >= 0; y--) {

            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1);

            isStop = false;

            for (int pix : pixs) {

                if (pix != Color.TRANSPARENT) {

                    bottom = y;

                    isStop = true;

                    break;

                }

            }

            if (isStop) {

                break;

            }

        }

        pixs = new int[HEIGHT];

        for (int x = 0; x < WIDTH; x++) {

            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT);

            isStop = false;

            for (int pix : pixs) {

                if (pix != Color.TRANSPARENT) {

                    left = x;

                    isStop = true;

                    break;

                }

            }

            if (isStop) {

                break;

            }

        }

        for (int x = WIDTH - 1; x > 0; x--) {

            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT);

            isStop = false;

            for (int pix : pixs) {

                if (pix != Color.TRANSPARENT) {

                    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(bp, left, top, right - left, bottom - top);

    }

    private void scanMediaFile(File photo) {

        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        Uri contentUri = Uri.fromFile(photo);

        mediaScanIntent.setData(contentUri);

        getContext().sendBroadcast(mediaScanIntent);

    }

}

相关文章

网友评论

      本文标题:电子合同签名 自定义View

      本文链接:https://www.haomeiwen.com/subject/nsjaqktx.html