在最近 haoyo择校 功能中,需要上传各个高校的招生计划图片;为申明版权,故需要在上传图片时添加水印。
技术栈:
vue2.x
+element-ui
+more...
实现思路:
- 利用
element-ui
的upload
组件,监听http-request
事件,获取到上传的文件信息。 - 将获取到的文件信息file, 转为base64格式。
- 将base64格式的图片转为canvas格式,并获取到canvas的图片对象。
- 给canvas图层添加水印。
- 将canvas图层转为图片格式(.jpg, .png….)。
- 将图片转为文件格式去上传。
代码示例:
入口方法
beforeUpload(file) {
console.log(file)
return new Promise((resolve, reject) => {
//把文件转换为base64
this.fileByBase64(file, async (base64) => { // 1.调用方法1: 把文件转换为base64字符串
// 把文件转换为Canvas
let tempCanvas = await this.imgToCanvas(base64) // 2. 调用方法2:把base64转换为Canvas
// 把水印写入
const canvas = this.addWatermark(tempCanvas, '考研公众号:HaoYo') //3.调用方法3: 写入水印到Canvas
// canvas转成img
const img = this.convasToImg(canvas, file.type) //4. 调用方法4:把Canvas转换为image文件
//被canvas转换为文件
let newFile = this.base64ToFile(img.src, file.name) //5.调用方法5:被image转换为File文件
resolve(newFile)
})
})
},
文件转base64
/**
* 文件转base64
* @param file 文件流
* @param callback 回调函数
*/
fileByBase64(file, callback){
let reader = new FileReader();
// 传入一个参数对象即可得到基于该参数对象的文本内容
reader.readAsDataURL(file);
reader.onload = function (e) {
// target.result 该属性表示目标对象的DataURL
callback(e.target.result)
};
},
Base64转成canvas
/**
* Base64转成canvas
* @param base64
*/
async imgToCanvas(base64) {
// 创建img元素
const img = document.createElement('img')
img.setAttribute('src', base64)
await new Promise((resolve) => (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
},
给canvas添加水印
/**
* canvas添加水印
* @param canvas 对象
* @param text 水印文字
*/
addWatermark(canvas, text) {
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#aaa'
ctx.textBaseline = 'middle'
ctx.font = (ctx.canvas.width / 20) + 'px Arial'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
// ctx.rotate(45);
// ctx.rotate((45 * Math.PI) / 180);
ctx.fillText(text, canvas.width / 2, canvas.height / 2)
return canvas
},
canvas转成img
/**
* canvas转成img
* @param {canvas对象} canvas
*/
convasToImg(canvas, type) {
// 新建Image对象,可以理解为DOM
let image = new Image()
// canvas.toDataURL 返回的是一串Base64编码的URL
// 指定格式 PNG
image.src = canvas.toDataURL(type)
return image
},
将img图片转为file类型的文件(用于上传)
/**
* @param urlData base64
* @param fileName 文件名称
* @returns {File}
*/
base64ToFile(urlData, fileName) {
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 });
},
最后图片,就开开心心的被加上水印了呀~
created_at:zhanghaoran’s blog 2022-04-25