vue+canvas 生成签名图片并保存数据库

VUE+ElementUI

最近根据项目需求 在用户生成订单的时候需要附上自己的签名照片,因为考虑到不能上传图片所以使用canvas画图功能。
而目前后台接口接收的只是一个字符串 ,所以


1.前端需要把canvas画出的签名生成图片
2.把图片上传到服务器生成路径,把路径地址保存到数据库
3.在下次修改编辑的时候需要把图片地址生成图片赋值到canvas中

遇到的问题
1.如何用canvas生成图片
2.如何把生成的图片使用图片上传接口上传到数据库
3.下次编辑时如何把网络图片地址生成图片并且赋值到canvas中

在这里插入图片描述

<template>
	<section>
		<el-form ref="form" :model="form" :rules="rules" label-width="120px">
			....
			<el-form-item label="签名" prop="signature" class="signatureName">
            	<div class="boardBox" ref="boardBox">
            		<canvas width="680" height="300" ref="board" @mousedown="pcStart" @mousemove="pcMove" @mouseup="pcEnd"> </canvas>
            	</div>
            	<el-button size="mini" type="primary" @click="clear">重新签名</el-button>
            </el-form-item>
			....
		</el-form>
	</section>
</template>
<script>
	export default {
		data(){
			return{
				ctx: null,
	            point: {
	                x: 0,
	                y: 0
	            },
	            moving: false,   // 是否正在绘制中且移动
			}
		},
		created(){
			
		},
		mounted(){
			this.start()
		},
		methods:{
			start(){
	            let board = this.$refs.board;   // 获取DOM
	            board.width = this.$refs.boardBox.offsetWidth;  // 设置画布宽
	            board.height = this.$refs.boardBox.offsetHeight;    // 设置画布高
	            this.ctx = board.getContext('2d');   // 二维绘图
	            this.ctx.strokeStyle = '#000';   // 颜色
	            this.ctx.lineWidth = 2;  // 线条宽度
	        },
	        // 鼠标按下(开始)
	        pcStart (e) {
	            let x = e.offsetX, y = e.offsetY;   // 获取鼠标在画板(canvas)的坐标
	            this.point.x = x;
	            this.point.y = y;
	            this.ctx.beginPath();
	            this.moving = true;
	        },
	        // 鼠标移动(移动中...)
	        pcMove (e) {
	            if(this.moving) {
	                let x = e.offsetX, y = e.offsetY;   // 获取鼠标在画板(canvas)的坐标
	                this.ctx.moveTo(this.point.x, this.point.y);    // 把路径移动到画布中的指定点,不创建线条(起始点)
	                this.ctx.lineTo(x, y);  // 添加一个新点,然后创建从该点到画布中最后指定点的线条,不创建线条
	                this.ctx.stroke();  // 绘制
	                this.point.x = x, this.point.y = y;   // 重置点坐标为上一个坐标
	            }
	        },
	        // 鼠标松开(结束)
	        pcEnd () {
	            if(this.moving) {
	                this.ctx.closePath();   // 停止绘制
	                this.moving = false;    // 关闭绘制开关
	            }
	        },
	        clear(){
	            this.$refs.board.getContext("2d").clearRect(0,0,800,600)
	        },
		}
	}
</script>

解决问题
1.如何把canvas生成图片并且把生成的图片上传数据库

1.使用canvas toDataURL将canvas生成base64图片  并把base64转换成文件
toImg(){
    var image = new Image();
    this.myImage = this.$refs.board.toDataURL("image/png")
    image.src = this.$refs.board.toDataURL("image/png");
    this.dataURLtoFile( this.myImage,'signature.png')
    return image;
},
dataURLtoFile(dataurl, filename) {//将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png)
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    this.fileList = new File([u8arr], filename, {type:mime});
    this.update(this.fileList)//图片上传
    return new File([u8arr], filename, {type:mime});
},
//上传
update(file){
	let param = new FormData(); //创建form对象
    param.append('file',file,file.name);//通过append向form对象添加数据  
    //this.uploadImgUrl 后台图片上传接口
    //param上传的文件
    //this.headers:{
    //  Authorization: 'Bearer ' + getToken(),//根据自己项目要求添加
    //  'Content-Type':'multipart/form-data',//必须添加
	//}
	/*
		原本考虑使用Element上传文件接口 可是无奈element上传文件或图片需要点击上传或者选取文件再上传,
		不能直接把生成的文件或图片直接上传
	*/
    Axios.post(this.uploadImgUrl,param,{headers:this.headers}).then(response=>{
        if(response.data.code===200){
            this.form.signature = this.serverImgUrl+response.data.fileName;
        }else{

        }
    }).catch(e=>{
        this.msgError('签名照生成失败')
    })  
}

2.把网络路径图片 转换成图片

imageUrlToBase64(httpUrl) {
	//一定要设置为let,不然图片不显示
	let image = new Image();
	//解决跨域问题
	image.setAttribute('crossOrigin', 'anonymous');
	let imageUrl = httpUrl;
	image.src = imageUrl
	let that = this;
	//image.onload为异步加载
	image.onload = () => {
		//赋值到canvas中
		var canvas = this.$refs.board;
        canvas.width = image.width;
		canvas.height = image.height;
		canvas.getContext('2d').drawImage(image, 0, 0);
		//这里的dataurl就是base64类型
		var dataURL = canvas.toDataURL("image/png");
              
        this.myImage = dataURL;
	}
},
Logo

前往低代码交流专区

更多推荐