目录
前言:实现思路
步骤一、在界面使用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);
    }
} 
至此,前端成功解决照片+水印的功能~~~



















