Blog Details

  • Home  
  • 微信小程序开发--添加照片水印(canvas )

微信小程序开发--添加照片水印(canvas )

前言:当你在微信小程序中制作照片时,你可能需要添加水印,以便在分享时保护你的照片,并标识出你的品牌或网站。本文将介绍如何在微信小程序中添加照片水印。

最近接到个需求:

效果图:

我的环境:

系统:Windows 11

微信开发者工具:1.06.2209190

调试基础库:2.32.2

说下思路:就是创建一个画布 把照片放到画布上 在画一个水印 然后融合

根据我的需求 我是一个 上传控件开始 要求只能拍照 不能从相册选择

multiple="true"

preview-size="{{screenWidth*0.2}}"

file-list="{{ fileList }}"

bind:after-read="afterRead"

bind:delete="deleteImg">

重点是 capture="{{['camera']}}" 我用的vant控件 所以查看文档 可解决

然后 实现 拍照水印:

wxml:

这个 画布 我放在了屏幕之外 这样 就不用 display:none 而导致绘图白屏了~~

然后他的宽度 和 高度 根据图片的大小而改变的 双向绑定的

js:

/* 上传方法 */

afterRead(event) {

const that = this;

const {

file

} = event.detail;

// 获取当前时间和位置信息

const currentTime =this.data.currentDate+" "+this.data.signTime; //时间

const currentLocation = this.data.address ; //地址

const files = event.detail.file;

// 遍历每个文件对象

files.forEach((file, index) => {

// 获取图片宽度和高度

wx.getImageInfo({

src: file.path,

success(res) {

file.width = res.width;

file.height = res.height;

that.setData({

canvasWidthValue: res.width,

canvasHeightValue:res.height,

})

file.path = res.path;

// 将时间和位置信息添加到文件对象中

file.currentTime = currentTime;

file.currentLocation = currentLocation;

// 创建一个临时canvas对象 query

const query = wx.createSelectorQuery()

query.select('#mycanvas').fields({

node: true,

size: true

})

.exec(res => {

const canvas = res[0].node

const ctx = canvas.getContext('2d');

const img = canvas.createImage()

img.src = file.path

img.onload = function () {

//设置画布到校绘制原图到canvas中

ctx.canvas.width = file.width/2

ctx.canvas.height = file.height/2

ctx.drawImage(img, 0, 0, file.width/2, file.height/2)

// 设置水印字体大小、颜色和位置

ctx.font = "18px arial";

ctx.fillStyle = "#FFFFFF";

ctx.textAlign = "left";

ctx.textBaseline = "bottom";

// 绘制时间和位置信息到canvas中

ctx.fillText(currentTime, 10, 60);

that.drawText(ctx,currentLocation,10, 90 , 232,that.data.windowWidth/6*5) // 自动换行

setTimeout(() => {

// 将canvas转换成图片,并将其添加到文件对象中

wx.canvasToTempFilePath({

canvas: canvas,

success: (res) => {

file.path = res.tempFilePath;

// 上传包含水印的图片

wx.uploadFile({

url: `${config.server_add}:${config.server_port}/iboss/interface/upload/${app.globalData.iboss_user.id}/StaffClock`,

filePath: file.path,

name: 'file',

header: {

'content-type': 'multipart/form-data'

},

success(res) {

res.data = JSON.parse(res.data);

console.log('res',res);

if (res.data.code === 200) {

console.log('200');

let arr = that.data.fileList;

arr.push({

url: res.data.data.realUrl,

FilePath: res.data.data.url,

deletable: true,

FileName: file.path.substring(11)

});

that.setData({

fileList: arr

});

} else {

wx.showToast({

title: '图片上传失败',

image: '../../../static/image/error.png',

duration: 1000

});

}

},

fail(res) {

console.error('生成图片失败', res)

}

});

},

fail(res) {

console.error('失败', res)

}

});

}, 1000);

}

})

}

});

});

},

//canvas文本过长 自动换行

drawText: function(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {

console.log("woaini",canvasWidth)

var lineWidth = 0;

var lastSubStrIndex = 0; //每次开始截取的字符串的索引

for (let i = 0; i < str.length; i++) {

lineWidth += ctx.measureText(str[i]).width;

if (lineWidth > canvasWidth) {

ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分

initHeight += 16; //16为字体的高度

lineWidth = 0;

lastSubStrIndex = i;

titleHeight += 30;

}

if (i == str.length - 1) { //绘制剩余部分

ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);

}

}

// 标题border-bottom 线距顶部距离

titleHeight = titleHeight + 10;

return titleHeight

},

大功告成~~~