uniapp给照片使用canvas画水印,任意数量水印文字位于左下角不会被遮盖且自动换行
前言
本文讲的是,文字数量不确定、文字种类不确定时,如何在水印左下角画图时,自动换行。
实现效果如下:根据文字自适应水印


总体思路还是非常简单的,canvas画图是从左上角开始。
计算出文字的行数,计算出文字总体高度,画布高度-文字高度作为水印起始高度
换行就是通过画布宽度/文字宽度,计算每一行能放的文字数量
详细思路
将不同列文字组成一个数组A,例如arr=['记录人:didi','时间:2022-04-01']
获取画布宽度
文字总数/画布宽度来计算行数,
画布高度-行高*行数作为起始高度
画布宽度/文字宽度,计算每行能放下的文字数量
将文字切割成数组,数组的每个子元素放置相应数量的文字
代码
onLoad(){
//获取水印内容,otherWaterData是数组形式,如['记录人:didi','时间:2022-01-01‘]
let otherWaterData = this.$store.state.waterStore;
this.otherWaterData = JSON.parse(JSON.stringify(otherWaterData));
}
//参数是水印信息waterData为数组、画布宽度
waterHandle(waterData, canvasWidth) {
//转化为字符串 let waterString = waterData.join(",");
//获取水印的宽度 let waterWidth = waterString.length * 12;
//获取一行能放置的字数,字的宽度设为12 let oneLineWaterNum = Math.floor(canvasWidth / 12); //切割数组 let newWaterData = []; for (let i = 0; i < waterData.length; i++) { let item = waterData[i]; //子项字数小于一行能放下的字数,不换行 if (item.length < oneLineWaterNum) { newWaterData.push(item) } else { let itemWidth = item.length * 12; //字数宽度 let itemLineNum = Math.ceil(itemWidth / canvasWidth); //分为几行 let start = 0; let end = start + oneLineWaterNum; for (let i = 0; i < itemLineNum; i++) { newWaterData.push(item.slice(start, end)); start = end; end = start + oneLineWaterNum; } } } return newWaterData; },
canvasWather(res) {
let that = this;
let ctx = uni.createCanvasContext('firstCanvas', this);
that.imgPath = res.path
let canvasWidth = res.width / 2;
let canvasHeight = res.height / 2;
that.w = canvasWidth + 'px';
that.h = canvasHeight + 'px';
setTimeout(() => {
//搜集水印数据
let waterData = that.otherWaterData;
//处理水印数据
let waterContentPosition = that.waterHandle(waterData, canvasWidth)
//初始化画布
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// //将图片src放到cancas内,宽高为图片大小
ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight);
//开始绘画,字体大小为10,颜色为白色
ctx.beginPath()
ctx.setFontSize(10)
ctx.setFillStyle('#FFFFFF');
//行数
let lineNum = waterContentPosition.length;
//行高
let lineHeight = lineNum * 16;
//画布高度-行高=开始绘制高度
let top = canvasHeight - lineHeight;
waterContentPosition.forEach((item, index) => {
//内容,左边距,上边距
ctx.fillText(item, 10, top + index * 16)
})
ctx.draw(false, () => {
uni.canvasToTempFilePath({ //将画布中内容转成图片,即水印与图片合成
canvasId: 'firstCanvas',
success: (res) => {
//水印生成成功,可以将图片保存到本地了
that.saveFile(res);
},
fail: (err) => {
that.showToastHandler('图片水印绘制失败!')
}
})
})
}, 500)
},
开源中国博客地址:https://my.oschina.net/u/2998098/blog/1540520

浙公网安备 33010602011771号