今天介绍一下,如何在上传的图片中添加水印。以下是一个使用nextjs实现的demo,具体水印位置可根据场景来自行配置。
添加水印技术点
- 获取原始图片尺寸,即naturalHeight和naturalWidth
- 创建相同尺寸的canvas画布
- 添加水印(水印文案,样式,位置)
- 将绘制成功的canvas,转成文件格式,发送给服务器
代码实现
- 获取原始图片尺寸
// 处理文件选择
const handleFileChange = (e: React.ChangeEvent) => {
if (!e.target?.files) return
const file = e.target.files[0];
// 清空图片
URL.revokeObjectURL(imageSrc as string)
//新建url
const url = URL.createObjectURL(file)
const img = new Image();
img.src = url;
//onload获取图片原始尺寸
img.onload = () => {
const { naturalWidth, naturalHeight } = img;
setImageInfo({
width: naturalWidth,
height: naturalHeight
});
};
setImageSrc(url)
};
- 创建相同规格的canvas画布,并绘制图片
const ctx = canvas.getContext("2d");
//imageInfo 上一步获取的图片尺寸
const { width, height } = imageInfo;
// 设置Canvas大小与裁剪框一致
canvas.width = width;
canvas.height = height;
// 将裁剪区域的图片绘制到Canvas中
ctx.drawImage(
imageRef.current,
0,
0,
);
- 添加水印
// 添加签名
ctx.font = '40px Arial';
ctx.fillStyle = 'white';
ctx.lineWidth = 2;
// 计算签名位置
const text = `Summer ${day().format('YYYY-MM-DD')}`;
const textWidth = ctx.measureText(text).width;
const padding = 40;
const x = width - textWidth - padding;
const y = height - padding;
// 绘制签名
ctx.fillText(text, x, y);
- 将绘制成功的canvas,转成文件格式,发送给服务器
// 将Canvas内容转换为File
canvas.toBlob(
(blob: Blob | null) => {
if (!blob) return
//使用newF File将blob数据转为file格式,便于使用formdata传数据
setCanvasBlobFile(new File([blob], 'watermark-image.jpg', { type: 'image/jpeg' }))
const url = URL.createObjectURL(blob) as string;
setwaterImage(url);
},
"image/jpeg",
0.7
);
- 上传服务器
// 上传加水印后的图片
const handleUpload = async () => {
if (!canvasBlobFile) return
const formdata = new FormData();
formdata.append('file', canvasBlobFile);
formdata.append('fileName', canvasBlobFile.name);
const res = await POST('/api/upload', {
data: formdata
});
if (res.code === 0) {
const { data } = res;
setUploadInfo(data)
}
};
- 支持下载
//下载图片
const handleDownload = () => {
if (!uploadInfo.url) return
let a = document.createElement('a');
a.href = uploadInfo.url;
a.download = uploadInfo.name;
a.click();
}
页面展示
- 图片预览
- 上传服务(支持链接下载)
这个图片添加水印和上传功能是使用nextjs来实现的,前端界面和服务端文件上传功能都是在同一个项目里实现,用起来很方便,很适合去做一些简易的demo。