图片上传大家都不会陌生,就算是一个新人也会干的事儿。但说到加水印,当初我一直以为只能是在后端实现。
原来,在前端也是能实现图片上传加水印的。(注:以下的代码都来自于网络,只是我把两部份代码合在一起来实现我的需求而已,在最后面,我也会附上原作者的接,大家都不容易)
【注:我自己写的注释后面会有个”(小冰)”,其他的为原作者的注释】
data(){ fileList:[], //vant中图片上传的双向邦定(小冰) wmConfig : { //用于水印的东西,下面会用到 (小冰) font: "microsoft yahei", //字体 textArray: ['张三','2021/11/26 16:44'],//水印文本内容,允许数组最大长度3 即:3行水印 density: 3 //密度 建议取值范围1-5 值越大,水印越多,可能会导致水印重叠等问题,慎重!!! } }
methods:{ //dataURLtoBlob 、 blobToFile 两个方法的意思是把base64的图片转换成file文件 //1,先将base64转换为blob dataURLtoBlob(dataurl) { 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); } return new Blob([u8arr], { type: mime }); }, //2,再将blob转换为file blobToFile(theBlob, fileName){ theBlob.lastModifiedDate = new Date(); // 文件最后的修改日期 theBlob.name = fileName; // 文件名 return new File([theBlob], fileName, {type: theBlob.type, lastModified: Date.now()}); }, //这个不多说,都懂,文件上传的方法(小冰) async afterRead(file){ console.log(file) let base64 = file.content; let res = await this.base64AddWaterMaker(base64,this.wmConfig) //加水印的重点就是这个(小冰) file.content = res; let blob = this.dataURLtoBlob(file.content); // 拿到文件名 let fileName = file.file.name; // 2,在转为 file类型 let file1 = this.blobToFile(blob,fileName); console.log("file1:",file1); }, base64AddWaterMaker (base64Img, wmConfig) { let that = this; if (wmConfig.textArray.length === 0) { console.error("****没有水印内容*****"); return base64Img; } return new Promise((resolve, reject) => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); let resultBase64 = null; img.onload = function() { canvas.width = img.width; canvas.height = img.height; //canvas绘制图片,0 0 为左上角坐标原点 ctx.drawImage(img, 0, 0); //写入水印 that.drawWaterMark(ctx, img.width, img.height, wmConfig); resultBase64 = canvas.toDataURL("image/png"); if (!resultBase64) { reject(); } else { resolve(resultBase64); } }; img.src = base64Img; }); }, drawWaterMark (ctx, imgWidth, imgHeight, wmConfig) { let fontSize; if (imgWidth >= 3456) { fontSize = 50; } else if (imgWidth >= 2700) { fontSize = 30; } else if (imgWidth >= 2000) { fontSize = 26; } else if (imgWidth >= 1436) { fontSize = 20; } else if (imgWidth >= 800) { fontSize = 12; } else if (imgWidth >= 500) { fontSize = 10; } else { fontSize = 8; } console.log(imgWidth, imgHeight, fontSize); ctx.fillStyle = "white"; ctx.font = `${fontSize}px ${wmConfig.font}`; ctx.lineWidth = 1; ctx.fillStyle = "rgba(255,255,255,1)"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; //文字坐标 const maxPx = Math.max(imgWidth, imgHeight); const stepPx = Math.floor(maxPx / wmConfig.density); let arrayX = [0];//初始水印位置 canvas坐标 0 0 点 while (arrayX[arrayX.length - 1] { return -el; })); console.log(arrayX); for (let i = 0; i 3) { wmConfig.textArray = wmConfig.textArray.slice(0, 3); } wmConfig.textArray.forEach((el, index) => { let offsetY = fontSize * index + 2; ctx.fillText(el, arrayX[i], arrayX[j] + offsetY); }); ctx.restore(); } } } }
代码就是这些,然而,在此中,我是把图片加水印和图片base64转file两个不同的博文混在一起写的。
图片加水印 :JavaScript实现为图片添加水印的方法
base64转file:JS中将图片base64转file文件的两种方式
顺便我也把file文件转base64的封装函数也发一下。当然,这个我也是在网上找的。
function fileToBase64(file, callback) { //callback 是一个回调函数,而回调函数往这儿走一回,它结果就是base64 const fileReader = new FileReader() fileReader.readAsDataURL(file) fileReader.onload = function () { callback(this.result) } }, function callbaseFun(res){ console.log(res,'res打印出来就是base64') },
//—————————分割线——————–
第二种方法,跟上面的方法差不多,只是这种方法可以随意去调整水印的位置和大小什么的。
//将base64转化为二进制 dataURItoBlob(base64Data) { var date = new Date(); //console.log('将base64转化为二进制', date.getMinutes(), date.getSeconds()) var byteString; if (base64Data.split(',')[0].indexOf('base64') >= 0) byteString = atob(base64Data.split(',')[1]); else byteString = unescape(base64Data.split(',')[1]); var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]; var ia = new Uint8Array(byteString.length); for (var i = 0; i = 0) byteString = atob(base64Data.split(',')[1]); else byteString = unescape(base64Data.split(',')[1]); var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]; var ia = new Uint8Array(byteString.length); for (var i = 0; i (img.onload = resolve)) // 创建canvas DOM元素,并设置其宽高和图片一样 const canvas = document.createElement('canvas') //console.log(img.height) //console.log(img.width) canvas.width = img.width canvas.height = img.height // 坐标(0,0) 表示从此处开始绘制,相当于偏移。 canvas.getContext('2d').drawImage(img, 0, 0) return canvas }, //写入水印 addWatermark(canvas, txt1, txt2, txt3, tex4) { //alert(canvas.height) var date = new Date(); //console.log('写入水印', date.getMinutes(), date.getSeconds()) const ctx = canvas.getContext('2d') //ctx.font = '50px Arial' //ctx.strokeText(text, 0, 0) ctx.font = '20px Arial' ctx.fillStyle = 'white' ctx.fillText(txt1, 20, canvas.height - 240) ctx.fillText(txt2, 20, canvas.height - 200) ctx.fillText(txt3, 20, canvas.height - 160) ctx.fillText(tex4, 20, canvas.height - 120) ctx.fillText(tex4, 20, canvas.height - 80) return canvas }, //Canvas转图片文件(Image) convasToImg(canvas) { var date = new Date(); //console.log('Canvas转图片文件(Image)', date.getMinutes(), date.getSeconds()) // 新建Image对象,可以理解为DOM let image = new Image() // canvas.toDataURL 返回的是一串Base64编码的URL // 指定格式 PNG image.src = canvas.toDataURL('image/png') return image }, //图片文件(Image)转文件(File) base64ToFile(urlData, fileName) { var date = new Date(); //console.log('图片文件(Image)转文件(File)', date.getMinutes(), date.getSeconds()) let arr = urlData.split(','); let mime = arr[0].match(/:(.*?);/)[1]; let bytes = atob(arr[1]); // 解码base64 let n = bytes.length let ia = new Uint8Array(n); while (n--) { ia[n] = bytes.charCodeAt(n); } return new File([ia], fileName, { type: mime }); }, //file对象转base64 fileToBase64(file, callback) { //callback 是一个回调函数,而回调函数往这儿走一回,它结果就是base64 var date = new Date(); //console.log('file对象转base64', date.getMinutes(), date.getSeconds()) return new Promise((resolve, reject) => { const fileReader = new FileReader() fileReader.readAsDataURL(file) fileReader.onload = function () { let res = callback(this.result) resolve(res) } }) }, callbaseFun(res) { //console.log('上传的方法') return new Promise((resolve, reject) => { let that = this; //console.log(res, 'base64') let str = res.split(','); str[0] = 'data:image/jpeg;base64'; let r = str.toString(); let url = "/ServerAPI/ServerBase64API.ashx" var obj = { imgbase64: r, method: "ServerBase64png", Module: "DaKa", id: "a4e89358-9465-4295-87ea-4d0af2bd9133" } jQuery.ajax({ url: url, type: 'POST', data: obj, dataType: 'json', timeout: 8000, }) .done(res => { var date = new Date(); //console.log('上传成功', date.getMinutes(), date.getSeconds()) //console.log('成功时执行') resolve(res) }) .fail(err => { //console.log(err, '上传失败') reject({ msg: '上传失败' }) }) }) },
async oneUpload(e){ let base64 = e.content; let tempCanvas = await this.imgToCanvas(base64) //得到canvas的值 const canvas = this.addWatermark(tempCanvas , '水印1' , '水印2' , '水印3'); //这儿水印的参数是根据 addWatermark()方法里面的 ctx.fillText(txt1, 20, canvas.height - 240) 进行修改 const img = this.convasToImg(canvas); //Canvas转图片文件(Image) let newFile = this.base64ToFile(img.src) //图片文件转file对象 let res = await this.fileToBase64(newFile, this.callbaseFun) //file转base64, 注意 第二个参数是一个回调函数,也就是说回调函数里面的参数就是base64的值 }
到此这篇关于Vue+vant实现图片上传添加水印的文章就介绍到这了,更多相关Vue vant图片加水印内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!