技术要点
- 使用
uni.getImageInfo 获取图片尺寸和路径。 - 使用
uni.createCanvasContext 在 canvas 上绘制图片和文字。 - 使用
ctx.drawImage 和 ctx.fillText 进行图像和文字渲染。 - 使用
uni.canvasToTempFilePath 导出带有水印的新图片。
页面结构(template)
<template><view><!-- Canvas 用于绘制水印 --><canvas canvas-id="watermarkCanvas" :style="{ width: `${canvasW}px`, height: `${canvasH}px` }" style="position: absolute; top: -10000px;"></canvas><!-- 显示最终带有水印的图片 --><image :src="completeImg" style="width: 200px; height: 200px;"></image></view>
</template>
逻辑实现(script )
<script setup lang="ts">
import { ref, watch } from 'vue';let canvasW = ref(0); // 画布宽度
let canvasH = ref(0); // 画布高度
let completeImg = ref<string>(''); // 带水印的图片地址/*** 添加水印函数* @param imagePath 图片原始路径* @param watermarkTexts 水印文字数组(多行)* @param textColor 文字颜色*/
function useAddWatermark(imagePath: string, watermarkTexts: Array<string>, textColor: string) {uni.getImageInfo({src: imagePath,success: (res) => {const imgWidth = res.width;const imgHeight = res.height;// 设置 canvas 尺寸与原图一致canvasW.value = imgWidth;canvasH.value = imgHeight;// 创建 canvas 上下文const ctx = uni.createCanvasContext('watermarkCanvas');// 绘制原始图片到 canvas 上ctx.drawImage(res.path, 0, 0, imgWidth, imgHeight);// 设置字体样式const fontSize = 16;const lineSpacing = 4;ctx.setFontSize(fontSize);ctx.setFillStyle(textColor);// 计算起始位置(左下角开始)const startX = 10;const startY = imgHeight - (watermarkTexts.length * (fontSize + lineSpacing) + 10);// 绘制每行文字watermarkTexts.forEach((text, index) => {ctx.fillText(text, startX, startY + index * (fontSize + lineSpacing));});// 执行绘制操作ctx.draw(false, () => {// 导出临时图片路径uni.canvasToTempFilePath({canvasId: 'watermarkCanvas',width: imgWidth,height: imgHeight,destWidth: imgWidth, // 目标宽度destHeight: imgHeight, // 目标高度fileType: 'jpg', // 指定文件类型为jpg以减小文件大小quality: 0.8, // 设置压缩质量success: (tempRes) => {completeImg.value = tempRes.tempFilePath;},fail: (err) => {console.error('导出图片失败', err);}});});},fail: (err) => {console.error('加载图片失败', err);}});
}</script>