Files
pasd_app/utils/watermark.js
2025-07-28 14:57:35 +08:00

97 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 新添加的水印功能----知无涯
/**
* 为图片添加水印
* @param {File} file - 原始图片文件
* @param {string} text - 水印文字
* @param {object} options - 水印配置选项
* @returns {Promise<File>} - 返回带水印的新图片文件
*/
export const addWatermarkToImage = (file, text, options = {}) => {
return new Promise((resolve, reject) => {
if (!file || !(file instanceof Blob)) {
reject(new Error('参数必须是Blob或File对象'));
return;
}
if (!text) {
reject(new Error('水印文字不能为空'));
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
try {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
// 绘制原始图片
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// 设置水印样式 - 增强可见性
// ctx.font = options.font || 'bold 20px Arial'; // 加大字号并加粗
// ctx.fillStyle = options.color || 'rgba(0, 0, 0, 0.7)'; // 改为黑色,提高不透明度
// ctx.textAlign = 'center';
// ctx.textBaseline = 'middle';
// 计算字体大小
const fontSize = Math.min(canvas.width, canvas.height) / 20; // 根据图片大小动态调整字体大小
ctx.font = `bold ${fontSize}px Arial`; // 加大字号并加粗
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; // 改为黑色,提高不透明度
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
// 添加文字阴影增强可读性
ctx.shadowColor = 'rgba(255, 255, 255, 0.8)';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
// 添加水印文字
//ctx.fillText(text, canvas.width / 2, canvas.height / 2);
// 拆分文本为多行
const lines = text.split('\n');
//const lineHeight = fontSize * 1.5; // 每行的高度,可以根据字体大小调整
//const startY = (canvas.height / 2) - ((lines.length - 1) * lineHeight / 2);
const lineHeight = fontSize * 1.5; // 每行的高度,可以根据字体大小调整
const startX = canvas.width - 10; // 右下角的x坐标留10像素的边距
let startY = canvas.height - 10; // 右下角的y坐标留10像素的边距
// 添加水印文字
// lines.forEach((line, index) => {
// ctx.fillText(line, canvas.width / 2, startY + index * lineHeight);
// });
lines.forEach((line) => {
const textWidth = ctx.measureText(line).width;
ctx.fillText(line, startX, startY);
startY -= lineHeight; // 每行向上移动一行的高度
});
// 清除阴影设置
ctx.shadowColor = 'transparent';
// 转换为Blob
canvas.toBlob((blob) => {
if (!blob) {
reject(new Error('图片转换失败'));
return;
}
const newFile = new File([blob], file.name || 'watermarked_image', {
type: file.type || 'image/jpeg',
lastModified: Date.now()
});
resolve(newFile);
}, file.type || 'image/jpeg');
} catch (error) {
reject(error);
}
};
img.onerror = () => reject(new Error('图片加载失败'));
img.src = e.target.result;
};
reader.onerror = () => reject(new Error('文件读取失败'));
reader.readAsDataURL(file);
});
};