技术要点
- 使用
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,
success: (tempRes) => {
completeImg.value = tempRes.tempFilePath;
},
fail: (err) => {
console.error('导出图片失败', err);
}
});
});
},
fail: (err) => {
console.error('加载图片失败', err);
}
});
}
</script>