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) },

  

posted @ 2022-06-02 11:17  大笛子  阅读(1494)  评论(0编辑  收藏  举报