服装企业网站内容规划,网店制作,什么是crm管理系统,最近的电脑培训学校前言前两天给个人网站添加了一个小功能#xff0c;就是在文章编辑上传图片的时候自动给图片加上水印。给网页图片添加水印是个常见的功能#xff0c;也是互联网内容作者保护自己版权的方法之一。本文简单记录一下借助canvas在前端实现图片添加水印的实现方法。canvas元素其实…前言前两天给个人网站添加了一个小功能就是在文章编辑上传图片的时候自动给图片加上水印。给网页图片添加水印是个常见的功能也是互联网内容作者保护自己版权的方法之一。本文简单记录一下借助canvas在前端实现图片添加水印的实现方法。canvas元素其实就是一个画布我们可以很方便地绘制一些文字、线条、图形等它也可以将一个img标签里渲染的图片画在画布上。我们在上传文件到后端的时候使用input标签读取用户本地文件后得到的其实是一个Blob对象更精确的说是File对象特殊的Blob对象而在页面上展示一个图片使用的是img标签绘制功能用canvas实现。添加水印的功能需要在img标签、canvas画布、Blob对象这三者之间相互转换通过一些API可以完成这个工作我们可以从本地读取图片Blob然后渲染到img标签使用canvas绘制img内容并且绘制水印内容到画布再将canvas内容转为Blob对象上传服务器这样就完整实现了图片水印的功能。一、本地读取图像文件渲染到img标签本地读取图片文件将会得到一个Blob对象我们可以借助FileReader.readAsDataURL方法读取Blob的内容并得到一个Base64编码的文件内容可以将该内容赋值给img.src从而在浏览器上渲染出本地的图像。当然img并非必须渲染到DOM树。读取操作是个异步操作读取完成会触发load事件为了便于之后的调用我们可以用一个Promise包装这个操作最后返回一个Promise对象。function blobToImg (blob) {return new Promise((resolve, reject) {let reader new FileReader()reader.addEventListener(load, () {let img new Image()img.src reader.resultimg.addEventListener(load, () resolve(img))})reader.readAsDataURL(blob)})
}二、将img标签内容绘制到canvas画布调用canvas元素画布上下文对象的drawImage方法即可实现将img内容绘制到画布。function imgToCanvas (img) {let canvas document.createElement(canvas)canvas.width img.widthcanvas.height img.heightlet ctx canvas.getContext(2d)ctx.drawImage(img, 0, 0)return canvas
}drawImage这个方法可以传入多个参数以定义绘制的图像的范围这里传入的0, 0定义从图像左上角开始绘制后面可以继续传入两个参数来定义图像的绘制终点不过这里整个图片都要绘制到canvas所以采用默认值即可。三、canvas画布上绘制水印并转换为Blob对象在图片上传的时候我们通常采用FormData图片文件以一个Blob对象的形式放到FormData中所以我们需要把canvas再转为Blob以便文件上传等操作。利用HTMLCanvasElement.toBlob方法function watermark (canvas, text) {return new Promise((resolve, reject) {let ctx canvas.getContext(2d)// 设置填充字号和字体样式ctx.font 24px 宋体ctx.fillStyle #FFC82C// 设置右对齐ctx.textAlign right// 在指定位置绘制文字这里指定距离右下角20坐标的地方ctx.fillText(text, canvas.width - 20, canvas.height - 20)canvas.toBlob(blob resolve(blob))})
}四、图片添加水印完整接口将以上三个步骤结合起来就完整地实现了从图片添加水印下面是一个简单的使用示例从本地选择一个图片文件然后添加水印后在传入的dom元素下预览添加水印后的图片。function imgWatermark (dom, text) {let input document.createElement(input)input.setAttribute(type, file)input.setAttribute(accept, image/*)input.onchange async () {let img await blobToImg(input.files[0])let canvas imgToCanvas(img)let blob await watermark(canvas, text)// 此处将Blob读取到img标签并在dom内渲染出来如果是上传文件可以将blob添加到FormData中let newImage await blobToImg(blob)dom.appendChild(newImage)}input.click()
}给页面加一个id为container的div元素然后如下调用let dom document.querySelector(#container)
imgWatermark(dom, 水印文字)这样就完整地给图片添加了水印效果下面看一下实际效果你也可以在线体验。添加水印前添加水印后水印内容“腾冲·清凉山”五、总结本文仅仅介绍了图像水印文字的简单实现但是涉及的一些接口其实很有用。比如有时候遇到的一个功能是头像上传的预览和剪裁这时候你可以利用FileReader来读取文件内容预览利用CanvasRenderingContext2D.drawImage来实现剪裁功能。关于本文接口的更多详细用法可以参照MDN文档文章中的api都使用了链接的形式链接到了MDN。