uniapp开发实现图片添加水印
需求:最近在开发uniapp项目,一直在加新的需求,根据要求,需要给上传图片添加水印,在网上参考了很多大佬的实现方案,自己进行了简单的封装,大家如有需要可以进行参考
主要代码展示:
1.首先创建画布
<canvas
canvas-id="cid3"
:style="{ height: `${cvHeight}px`,width: `${cvWidth}px`}"
>
</canvas>
1.传入图片地址,获取图片大小
export const getImageSizeByUrl = (url)=>{
return new Promise((resolve, reject) => {
// app中只能使用uni.getImageInfo获取图片信息
uni.getImageInfo({
src:url,
success:function(res) {
resolve({
width: res.width,
height: res.height,
});
},
fail:function(err){
reject(new Error("getImageSizeByUrl 加载图片失败"));
}
})
})
}
2.将图片进行压缩处理
// 如果最长边大于350,计算缩放比例.如果最长边不大于350,直接返回原始尺寸
export const scaleImage = (width, height)=>{
return new Promise((resolve, reject) => {
// 找到较长的一边
const maxSide = Math.max(width, height);
// 如果最长边大于350,计算缩放比例
if (maxSide > 350) {
const scale = 350 / maxSide;
// 使用缩放比例来调整图片的长宽
const newWidth = Math.round(width * scale);
const newHeight = Math.round(height * scale);
resolve({
width: newWidth,
height: newHeight,
});
} else {
// 如果最长边不大于350,直接返回原始尺寸
resolve({
width,
height,
});
}
});
}
3.画水印
// 画水印
function imgToCanvas(url, width, height) {
return new Promise((resolve, reject) => {
const ctx = uni.createCanvasContext("cid3"); //在dom元素中定义了一个不显示的canvas元素
ctx.clearRect(0, 0, width, height);
ctx.drawImage(url, 0, 0, width, height);
// 设置文字水印的大小,位置
ctx.setFontSize(12);
ctx.setFillStyle("rgba(255,255,255,0.5)");
const watermarkText = "你的水印";
const textWidth = ctx.measureText(watermarkText).width;
const textX = width - textWidth - 10
const textY = height - 5 - 10
// 添加水印C
ctx.fillText(
watermarkText,
textX,
textY
);
setTimeout(() => {
// 绘制到canvas上,返回加完水印的 base64 url
ctx.draw(false, async() => {
uni.canvasToTempFilePath(
{
canvasId: "cid3",
fileType: "jpg",
success: (res) => {
resolve(res.tempFilePath)
},
fail: (err) => {
reject(err);
},
},
true // 替换整个画布元素
);
});
},1000)
});
}
4.封装主方法,进行生成
// 静态图片添加水印
export const imageAddWatermarks = async(url,width,height) =>{
try {
let waterUrl = await imgToCanvas(url, width, height);
return waterUrl
} catch (error) {
console.error(error);
}
}
完整封装代码展示:
// 静态图片添加水印
export const imageAddWatermarks = async(url,width,height) =>{
try {
let waterUrl = await imgToCanvas(url, width, height);
return waterUrl
} catch (error) {
console.error(error);
}
}
// 获取图片大小,压缩图片
export const getImageSizeByUrl = (url)=>{
return new Promise((resolve, reject) => {
// app中只能使用uni.getImageInfo获取图片信息
uni.getImageInfo({
src:url,
success:function(res) {
resolve({
width: res.width,
height: res.height,
});
},
fail:function(err){
reject(new Error("getImageSizeByUrl 加载图片失败"));
}
})
})
}
// 如果最长边大于350,计算缩放比例.如果最长边不大于350,直接返回原始尺寸
export const scaleImage = (width, height)=>{
return new Promise((resolve, reject) => {
// 找到较长的一边
const maxSide = Math.max(width, height);
// 如果最长边大于350,计算缩放比例
if (maxSide > 350) {
const scale = 350 / maxSide;
// 使用缩放比例来调整图片的长宽
const newWidth = Math.round(width * scale);
const newHeight = Math.round(height * scale);
resolve({
width: newWidth,
height: newHeight,
});
} else {
// 如果最长边不大于350,直接返回原始尺寸
resolve({
width,
height,
});
}
});
}
// 画水印
function imgToCanvas(url, width, height) {
return new Promise((resolve, reject) => {
const ctx = uni.createCanvasContext("cid3"); //在dom元素中定义了一个不显示的canvas元素
ctx.clearRect(0, 0, width, height);
ctx.drawImage(url, 0, 0, width, height);
// 设置文字水印的大小,位置
ctx.setFontSize(12);
ctx.setFillStyle("rgba(255,255,255,0.5)");
const watermarkText = "你的水印";
const textWidth = ctx.measureText(watermarkText).width;
const textX = width - textWidth - 10
const textY = height - 5 - 10
// 添加水印C
ctx.fillText(
watermarkText,
textX,
textY
);
setTimeout(() => {
// 绘制到canvas上,返回加完水印的 base64 url
ctx.draw(false, async() => {
uni.canvasToTempFilePath(
{
canvasId: "cid3",
fileType: "jpg",
success: (res) => {
resolve(res.tempFilePath)
},
fail: (err) => {
reject(err);
},
},
true // 替换整个画布元素
);
});
},1000)
});
}
最后附上使用方法:
//在需要用到的界面导入
import {getImageSizeByUrl,scaleImage,imageAddWatermarks} from '@/utils/watermark.js'
//使用
const {
width,
height
} = await getImageSizeByUrl(item.url); //获取图片大小
const scaledImage = await scaleImage(width, height); //压缩图片
this.cvWidth = scaledImage.width
this.cvHeight = scaledImage.height // 将图片宽高给画布宽高,这样才能保持一致
//最后waterUrl 就是水印图片地址
let waterUrl = await imageAddWatermarks(item.url,this.cvWidth,this.cvHeight)