前言
最近公司的项目需求需要用到element上传组件上传图片,但是上传图片时必须要加上本公司的水印来保护公司产品用户的图片信息
技术栈
本方法用的 canvas 加 Elementui(换成组件都行)上传图片前加水印
一.html
<el-upload
:before-upload="imageUploadOther" //上传图片前钩子函数 可校验上传图片类型
:on-change="imgChange" //监听图片切换时的函数
accept=".png,.jpg" //软显示上传类型
class="avatar-uploader" //基础样式
>
<img
v-if="form.carPhotos[0].carPicture" //控制显示隐藏
:src="form.carPhotos[0].carPicture" //后端返回的的图片网络地址
class="avatar" //基础样式
/>
<i v-else class="el-icon-plus avatar-uploader-icon"></i> 加号icon
</el-upload>
二.js
1. imgChange(file){}监听图片上传的函数
参数file 组件自带车参数打印可获取图片信息图片基本信息 我,们需求要拿这个函数获取图片的本机地址
1 imgChange(file) {
2 // -----获取图片的本机路径------
3
4 let dialogImageUrl = window.URL
5 ? window.URL.createObjectURL(file.raw)
6 : window.webkitURL.createObjectURL(file.raw);
7
8 //-----调用封装好的函数处理图片------
9 this.shuiyin({
10 url: dialogImageUrl, //这里传的file是上传的图片文件
11 content: "我是水印", //水印内容
12 cb: (base64Url) => { //回调函数callBack()
13 this.base64Url = base64Url;
14 console.log(base64Url); //转换完成的base64格式图片在这里发送请求
15 },
16 });
17 },
18}
2. huiyin(url,textAlign,textBaseline,font,fillStyle,content,cb){} 添加水印函数
参数 :
-
url传入当前上传图片的本地路径 -
textAlign文字对齐方式 默认left -
textBaseline文字水平放置位置 默认top -
font文字字体和大小还有12px Microsoft Yahei -
fillStyle文字样式rgba(255, 255, 255, .3)颜色和透明度 -
content水印内容 -
cb回调函数callBack(base64Url)参数base64Url转换过的的路径可以提交给后台
1 shuiyin({
2 url = "",
3 textAlign = "left",
4 textBaseline = "top",
5 font = "38px Microsoft Yahei",
6 fillStyle = "rgba(255, 255, 255, .3)",
7 content = "",
8 cb = null,
9 } = {}) {
10 const img = new Image();
11 img.src = url;
12 img.crossOrigin = "anonymous";
13 img.onload = function () {
14 const canvas = document.createElement("canvas");
15 let _ix = img.width;
16 let _iy = img.height;
17 canvas.width = _ix;
18 canvas.height = _iy;
19 const ctx = canvas.getContext("2d");
20 ctx.drawImage(img, 0, 0);
21 ctx.textAlign = textAlign;
22 ctx.textBaseline = textBaseline;
23 ctx.font = font;
24 ctx.fillStyle = fillStyle;
25 ctx.translate(-20, 100);
26 ctx.rotate((Math.PI / 90) * -15); //旋转
27 //水印密度
28 for (let i = 0; i < _iy / 120; i++) {
29 for (let j = 0; j < _ix / 50; j++) {
30 ctx.fillText(content, i * 170, j * 100, _ix); //调节间距
31 }
32 }
33 const base64Url = canvas.toDataURL();
34 cb && cb(base64Url);
35 };
36 },
好的结束