整体实现流程:首先调用uni.chooseImage方法,配置count、sizeType、sourceType参数,分别代表选择的图片个数、original 原图,compressed 压缩图,默认二者都有、是从相册还是拍照。
然后在成功的回调中拿到上传的所有图片并存储。然后就是添加水印,调用uni-getImageInfo拿图片信息,然后使用canvas进行水印添加。在成功的回调中进行图片上传(uni-uploadFile)即回显。代码如下:
imgCount就是限制上传个数,当我们同时使用拍照和相册上传,会出现当上传一张拍照图片,再从相册上传这个如果不做imgCount--操作上传的个数会出现问题。也有其他实现形式哦。
如果我们在成功的回调中拿到所有图片,直接在success中循环调用添加水印方法。例如选择了两张图片就会出现上传的两张图片一摸一样。所以我没有在success中直接遍历。
/**选择图片*/selectPicture() {uni.chooseImage({count: this.imgCount,sizeType: ['compressed'], // 压缩图片sourceType: ['camera', 'album'], // 拍照或相册上传图片success: (res: any) => {this.imgCount-- // 这里主要为了限制选择的图片,解决图片先拍照上传,后有进行相册选择// 每次清空数组this.photoArr.length = 0// 存储上传的图片this.photoArr.push(...res.tempFiles.map((item: any) => item.path)) // 添加水印this.callAddWaterMart()}})}
这个callback方法就是为了在上传并添加水印后在给第二张图片添加。代码中也有注释,我就不多说了
// 调用添加水印的函数callAddWaterMart() {// 这个是真正的添加水印方法,传入回调是为了解决同时上传多张,会显示相同的图片。this.getInfoImage(() => {if (this.photoIndex < this.photoArr.length - 1) {this.photoIndex++this.callAddWaterMart()}})}// 这里为了方便写到一个函数里
getInfoImage(callback: any) {// 小程序没有document,只能在页面中建一个canvas,然后在成功时给他隐藏。this.flag = false// 这个函数是可以拿到图片的一些信息,宽高等uni.getImageInfo({// 初始化photoIndex=0,拿到第一张图片,并添加水印src: this.photoArr[this.photoIndex],success: res => {// // 设置画布高度和宽度this.canvasWidth = `${res.width}px`this.canvasHeight = `${res.height}px`//获取当前时间let roleNameInfo = date(new Date(), 'long') + '\n' + this.from.data.addressvar ctx = uni.createCanvasContext('imgId')ctx.drawImage(this.photoArr[this.photoIndex], 0, 0, res.width, res.height)// 为图片添加水印ctx.setFontSize(30) //水印字体大小ctx.setFillStyle('red') //水印颜色// 水印位置ctx.fillText(roleNameInfo, 60, res.height - 60)// 开始绘制添加水印的图片并显示在页面中ctx.draw(false, result => {setTimeout(() => {//把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas> 组件。// 这里主要为了拿到路径uni.canvasToTempFilePath({canvasId: 'imgId',// 设置输出的图片的宽度高度,会加快输出图片时间destWidth: res.width,destHeight: res.height,fileType: 'jpg', //jpg为了压缩quality: 0.8, //图片的质量success: res => {console.log('res', res)this.flag = true/** 添加上传进度和图片路径 */this.currentImgList.push({path: res.tempFilePath,uploadPercent: 0})// 上传图片this.uploadfile(res.tempFilePath)// 给所有的图片添加水印callback()},fail: err => {uni.hideLoading()// this.$u.toast('上传错误')}})}, 500)})},fail: err => {console.log(err)}})}
uploadFile我就不说了,每个公司都不一样的路径,看文档就可以了。这里只提示思路,代码大家自行实现。