目录
前言:实现思路
步骤一、在界面使用uview的u-upload组件、放置canvas标签
步骤二、在afterRead方法中获取照片url,并创建画布生成水印,再将生成水印的照片上传到服务器
1、afterRead方法
2、照片加水印的方法
3、上传照片至服务器
4、处理水印换行操作
最终实现照片加水印效果(水印内容可自定义):
前言:实现思路
我的实现思路:使用uview的u-upload组件,在上传照片时候会调用afterRead方法,可以获取上传附件的相关属性信息,拿到照片的url之后,调用uni.getImageInfo方法,在uni.getImageInfo的成功回调函数中使用uni.createCanvasContext创建画布,制作水印的文本信息,制作完成后再使用uni.canvasToTempFilePath将画布内容转成图片,再将要上传照片的路径转换成新生成的带有水印照片的url,调用接口完成上传,至此过程结束。
步骤一、在界面使用uview的u-upload组件、放置canvas标签
<u-form-item
label="技术/安全交底"
required
prop="JSAQJD"
>
<u-upload
:fileList="JSAQJD"
@afterRead="afterRead"
@delete="deletePic"
name="JSAQJD"
multiple
:maxCount="3"
>
</u-upload>
<view style="position: absolute;top: -999999px;">
<view>
<canvas style="width: 1000px;height: 1000px;" canvas-id="myCanvas"></canvas>
</view>
</view>
</u-form-item>
步骤二、在afterRead方法中获取照片url,并创建画布生成水印,再将生成水印的照片上传到服务器
this[`${e.name}`]其实就是对应的fileList,这里由于上传附件的位置很多,所以最好设置成动态的
1、afterRead方法
async afterRead(e){
// file name index
//生成水印
let data = await this.getWatermark(e.index,e.file[0].url);
e.file[0].url = data;
let lists = [].concat(e.file)
let fileListLen = this[`${e.name}`].length
lists.map((item)=>{
this[`${e.name}`].push({
...item,
status:'uploading',
message:'上传中'
})
})
for(let i=0;i<lists.length;i++){
const result_data = await this.uploadFilePromise(lists[i].url)
let item = this[`${e.name}`][fileListLen]
let img = THUMBNAIL + result_data
this[`${e.name}`].splice(fileListLen,1,Object.assign(item,{
status:'success',
message:'',
url:img
}))
fileListLen++
//附件的uuid更新 需做为空判断
this.form[`${e.name}`] += `,${result_data}`
}
},
2、照片加水印的方法
//照片水印
getWatermark(index, list){
return new Promise((resolve, reject) => {
var that = this;
uni.getImageInfo({
src: list,
success: (ress) => {
let ctx = uni.createCanvasContext('myCanvas'); //创建画布
//将图片src放到cancas内,宽高为图片大小
ctx.drawImage(list, 0, 0, ress.width / 3, ress.height / 3)
let textToWidth = ress.width / 3 * 0.03; //字体宽度
let textToHeight = ress.height / 3; //字体高度
//根据需求,自行设置
lineFeed(`拍摄:${that.userinfo.HUMANNAME}`, textToWidth, textToHeight * 0.8,ress.width / 3 * 0.9,ctx)
lineFeed(`时间:${getNowDate()}`, textToWidth, textToHeight * 0.85,ress.width / 3 * 0.9,ctx)
lineFeed(`地址:${that.address}`, textToWidth, textToHeight * 0.9,ress.width / 3 * 0.9,ctx)
ctx.draw(false,()=>{
setTimeout(() => {//制作水印需要时间,这里最好设置定时
uni.canvasToTempFilePath({//内容转成图片
width: ress.width / 3, // 画布宽度
height: ress.height / 3, // 画布高度
canvasId: 'myCanvas',
success: (res) => {
list = res.tempFilePath
resolve(list);
}
})
}, 500)
});
}
})
})
},
3、上传照片至服务器
uploadFilePromise(url){
let vthis = this;
return new Promise((resolve,reject)=>{
let a = uni.uploadFile({
url:`xxxx/uploadFile.htm`,//设置为自己的后台接口
filePath:url,
name:'file',
formData:{
folderId:vthis.recid,
//存储路径,用日期标识
folderPath:getRq(),
recId:vthis.recid,
longitude:vthis.form.XZB,
latitude:vthis.form.YZB,
},
success:(res)=>{
if(res.statusCode == 200){
let o = JSON.parse(res.data)
resolve(o.data[0].fileId)
}
}
})
})
},
4、处理水印换行操作
export function lineFeed(a,x,y,w,context){
let chr = a.split("");
let temp = "";
let row = [];
context.font = 'normal bold 16px Arial,sans-serif '
context.setFillStyle('#FFA500') //字体颜色
for(let i = 0; i < chr.length; i++){
if( context.measureText(temp).width < w ){
;
}
else{
row.push(temp);
temp = "";
}
temp += chr[i];
}
row.push(temp);
for(let r = 0; r < row.length; r++){
context.fillText(row[r],x,y+(r+1)*20);
}
}
至此,前端成功解决照片+水印的功能~~~