-
选择图片
- 使用
uni.chooseImage
方法让用户选择一张图片。 - 成功选择后,调用
addWatermark
方法并传递图片路径。
- 使用
-
绘制图片和水印
- 使用
uni.getImageInfo
获取图片信息(如宽高)。 - 使用
uni.createCanvasContext
创建 Canvas 上下文。 - 使用
ctx.drawImage
绘制图片到 Canvas。 - 使用
ctx.fillText
添加水印文本。 - 使用
ctx.draw
方法完成绘制。
- 使用
-
保存为临时文件
- 在
ctx.draw
回调中,使用uni.canvasToTempFilePath
将 Canvas 内容保存为临时文件路径。 - 将生成的临时文件路径存储到
tempFilePath
数据属性,并显示在页面上
- 在
图片上传的方法:
canvas标签只起到一个承载的作用。当前的样例需要将加了水印的照片再上传到服务器,再展示服务器返回的图片地址,需要另外的标签展示。canvas展示的只是临时图片地址,所以设置其样式不可见。
//标签
<template>
<view class='content-body'>
<view class="row">
<view class="canvas">
<canvas canvas-id="canvas" class="canvas"
:style="`width: ${canvas.width}px; height: ${canvas.height}px; background-color: #ddd`" />
</view>
<!-- <uni-file-picker @select="select" @success="success" style="margin: 0 auto;" v-model="picArr"
fileMediatype="image" mode="grid" /> -->
<view class="box_images_upload" v-if="imageFilesarr&&imageFilesarr.length>0">
<view class="images-arr" v-for="(item,index) in imageFilesarr" :key='index'>
<!-- @click="navigateToExternalLink(item)" -->
<view class="link" v-if="item.contentType.includes('pdf')||item.contentType.includes('document')">
{{item.name}}
</view>
<view class="images-content" v-if="item.contentType.includes('image')">
<image class="delete-btn" src="../../static/icon/x.png" mode="" @click="ondelete(item)"></image>
<image class="imagesinfo" :src="item.url" mode=""></image>
</view>
</view>
<image src="../../static/icon/more.png" mode="" @click="uploadfile()"></image>
</view>
<view v-else class="box_images">
<view class="upload-box" @click="uploadfile()">
<image src="../../static/icon/wenjian.png" mode=""></image>
<view class="upload">上传照片</view>
</view>
</view>
</view>
</view>
</template>
//方法
watermark(file) {
function drawText(text, x, y, maxWidth) { //換行
let words = text.split('');
let line = '';
for (let n = 0; n < words.length; n++) {
let testLine = line + words[n];
let metrics = ctx.measureText(testLine);
let testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
ctx.fillText(line, x, y);
line = words[n];
y += 20; // 文本行高
} else {
line = testLine;
}
}
ctx.fillText(line, x, y);
}
const ctx = uni.createCanvasContext('canvas', this)
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: file,
success: (info) => {
this.canvas = info
setTimeout(() => {
ctx.drawImage(info.path, 0, 0, info.width, info.height)
ctx.draw()
ctx.setFontSize(32)
ctx.setFillStyle('red')
ctx.fillText(
`${this.loginUserInfo.name} ${this.loginUserInfo.loginname}`,
20, info.height - 20)
ctx.font = '136px 宋体'
ctx.draw(true)
ctx.setFontSize(32)
ctx.setFillStyle('red')
drawText(`${this.locationBean.address || ''}`, 0, info.height -
100, 350);//当前文本太长换行
// ctx.fillText(`${this.locationBean.address||''}`, 0, info
// .height - 60)
ctx.font = '136px 宋体'
ctx.draw(true)
setTimeout(() => {
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: info.width,
height: info.height,
fileType: 'jpg',
canvasId: 'canvas',//canvas标签的id
success: (res) => {
console.log('成功', res)
resolve(res)
},
fail: (err) => {
console.log('失败1', err)
}
}, this)
}, 100)
}, 100)
},
fail: (err) => {
console.log('失败2', err)
}
})
})
},
async upload() {//选择文件
let tempFilePaths = ''
if (this.item.id == 1) { //图片
uni.chooseImage({
count: 6, //默认9
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: async (result) => {
let url = result.tempFilePaths[0]
let res = await this.watermark(url)//图片打水印
tempFilePaths = res.tempFilePath
this.uploadFilearr(tempFilePaths)
}
})
} else if (this.item.id == 2) { //pdf
//选择pdf可以是使用uni.chooseFile,但是只兼容H5
}
},
uploadFilearr(tempFilePaths) {//图片上传
let protocol = ''
let projectName = ''
if (process.env.NODE_ENV === 'development') {//测试环境
protocol = process.env.HOST + '/'
projectName = 'cmms-single-test'
} else {
protocol = process.env.HOST
projectName = 'cmms-single'
}
// let host = window.location.host
const url = `${protocol}cmms-pro/workorder/v2/minio/upload`
console.log('tempFilePaths', tempFilePaths)
uni.uploadFile({
url: url,//图片上传完整URL
filePath: tempFilePaths,
name: 'file',
formData: {//其他参数
'projectName': projectName,
'moduleName': 'signin',
},
success: (uploadFileRes) => {
let res = JSON.parse(uploadFileRes.data)
let url = res.data.url
this.imageFilesarr.push(res.data)
this.imageValue.push(url)
console.log('res', res)
},
fail: (err) => {
console.log('错误', err)
}
});
this.$refs.showActionSheet.close()
},
//样式,canvas标签只起到一个承载的作用。当前的样例需要将加了水印的照片再上传到服务器,再展示服务器返回的图片地址,需要另外的标签展示。canvas展示的只是临时图片地址,所以设置其样式不可见。
.canvas {
position: absolute;
top: 0;
left: 0;
z-index: -1;
width: 1px;
height: 1px;
visibility: hidden;
overflow: hidden;
}