1、uniapp加水印
1.1、创建画布容器
<canvas class="watermark-canvas" id="watermark-canvas" canvas-id="watermark-canvas"
:style="{ width: canvasWidth, height: canvasHeight }" />
1.2、获取水印内容
async getLocation() {
const zero = (item) => item < 10 ? "0" + item : item
const time = new Date();
const yy = time.getFullYear();
const mm = time.getMonth() + 1;
const dd = time.getDay();
const hh = time.getHours();
const MM = time.getMinutes();
const ww = time.getDay()
const hm = zero(hh) + ':' + zero(MM)
const ymd = yy + '-' + zero(mm) + '-' + zero(dd)
const {
name: location
} = await this.$store.dispatch('location/juGetLocation')
return {
hm,
ymd,
address: location
}
},
1.3、添加水印上传图片
async chooseImage(e) {
// #ifdef APP-PLUS
let status = await this.checkPermission()
if (status !== 1) {
return
}
// }
// #endif
uni.chooseImage({
sourceType: sourceType[this.sourceTypeIndex],
sizeType: ['compressed'],
count: this.limit,
success: async (res) => {
let filePath = res.tempFilePaths[0]
const watermark = await this.getLocation()
//压缩图片设置宽度,不然画不全
uni.compressImage({
src: filePath,
quality: 80,
success: async comres => {
//绘制图片加水印
let img = await this.fillTextToImg(comres.tempFilePath, watermark)
uni.showLoading({
title: '上传中...',
mask: true
})
const arr = [img]
// 上传图片
const key = await this.$store.dispatch('upload/uploadFileList', arr)
this.$emit('handleChangeKeys', {
src: key,
create_time: watermark.hm,
sign_date: watermark.ymd,
sign_local: watermark.address
})
uni.hideLoading()
}
})
},
fail: (err) => {}
})
},
sleep(millisecond) {
return new Promise((resolve) => {
setTimeout(resolve, millisecond)
})
},
fillTextToImg(file, watermark) {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: file,
success: async res => {
//设置画布大小,然后再画,不然会只画一部分
this.canvasWidth = `${res.width}px`
this.canvasHeight = `${res.height}px`
await this.sleep(200)
const ctx = uni.createCanvasContext('watermark-canvas', this)
ctx.clearRect(0, 0, res.width, res.height)
ctx.beginPath()
ctx.drawImage(res.path, 0, 0, res.width, res.height)
// 水印 字体大小,颜色,内容,位置
ctx.beginPath()
ctx.setFillStyle('#ffffff')
const fontSize = res.width / 10
ctx.setFontSize(fontSize)
ctx.fillText(watermark.hm, res.width / 2 - res.width / 8, res.height / 2 - 50)
ctx.setFontSize(res.width / 15)
ctx.fillText(watermark.ymd, res.width / 2 - res.width / 6, res.height / 2 + 100)
ctx.setFontSize(res.width / 17)
ctx.fillText(watermark.address, res.width / 5 - 15, res.height / 1.5 + 50)
// 开始绘制 (canvas -> 临时文件路径)
ctx.draw(false, async () => {
await this.sleep(500) // 某些平台 canvas 渲染慢,需要等待
uni.canvasToTempFilePath({
canvasId: 'watermark-canvas',
destWidth: res.width,
destHeight: res.height,
fileType: 'jpg',
quality: 0.8,
success: (fileRes) => {
resolve(fileRes.tempFilePath)
},
fail: (err) => {
uni.showToast({
title: err.errMsg,
icon: 'none'
})
reject()
},
},
this,
)
})
},
fail: (err) => {
console.log('[Error getImageInfo]', err)
uni.showToast({
title: err.errMsg,
icon: 'none'
})
reject()
},
})
});
},
1.4、设置画布位置,不让其显示
.watermark-canvas {
transform: scale(1);
transform-origin: 0 0;
position: absolute;
top: -999px;
left: -999px;
}
2、web端加水印(Image,FileReaderweb端才能使用)
// 获取本地图片的base64编码
// 使用在线图片链接的时候需要注意给图片设置crossOrigin属性
function fileToBase64Async(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
resolve(e.target.result);
};
});
}
// fillText绘制的是默认的普通实线文本,strokeText绘制的是描边文本
function fillTextToImg(base64) {
const img = new Image();
img.src = base64;
img.setAttribute("crossOrigin", "Anonymous");
return new Promise((resolve, reject) => {
img.onload = () => {
// 生成一个 canvas 画布;
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// 将现有需要添加水印的图片绘制到画布上;
const ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const remFontSize = canvas.width / 35;
ctx.font = "bolder " + remFontSize + "px Verdana";
ctx.textAlign = "center";
/**
ctx.textAlign = "center|end|left|right|start";
start:默认,文本在指定的位置开始。
end:文本在指定的位置结束。
center:文本的中心在指定的位置。
left:文本左对齐。
right:文本右对齐。
**/
ctx.strokeStyle = "#fff";
const name = "@AAAAAAAAAAAAA";
const spaceH = remFontSize * 0.3;
ctx.fillText(
name,
canvas.width / 2,
canvas.height - remFontSize - spaceH
);
resolve(canvas.toDataURL("image/jpeg"));
};
});
}