=====================时间分割线========================
2020/09/21 前排更新了一下代码,多了“添加指定水印图片作为水印”(只显示一个在左上角),以及添加了适当的“自定义水印文字”
(可以修改旋转角度、颜色、字体大小)、两种情况下在左下角添加时间(自定义水印字因为加了旋转,添加时间时得反转)
预览
========================时间分割线=====================
场景/契机:
react项目使用了react-photo-view来实现图片查看,但是该组件无法在图片本身添加水印,又要求纯前端解决。为了纯前端得到一个含有水印的url故有此操作。
HTML代码:
<img id="showimg">
JS代码:
let previous_url = "http://i2.tiimg.com/704774/ce778c4938b3c7e2.jpg";
const reader = new FileReader();
const showimg = document.getElementById('showimg');//img元素
const canvas = document.createElement('canvas');
let source = new Image();
source.src = previous_url;
source.onload=()=>{
canvas.width = source.width;
canvas.height = source.height;
const ctx = canvas.getContext("2d")
let getImageBlob = (url, cb) => {
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status == 200) {
if(cb) cb(this.response);
}
};
xhr.send();
}
getImageBlob( previous_url , function(blob){
// previous_url = URL.createObjectURL(blob);
reader.readAsDataURL(blob);
});
reader.onload = (e) => {
// console.log(previous_url)
const img = document.createElement('img');
img.src = e.target.result;
img.onload=()=>{
ctx.drawImage(img,0,0)
ctx.font = "20px 宋体";
ctx.textBaseline = 'middle';
ctx.fillStyle="snow"
ctx.beginPath()
ctx.rotate(-20*Math.PI/180);
for(let x = -3; x*300<=source.width+900;x++){
for(let y = -3; y*200<source.height+600;y++){
ctx.fillText('e商城注册专用其他无效', 170+(300*x), 30+(200*y));
}
}
canvas.toBlob(blob=>{
previous_url = URL.createObjectURL(blob);
showimg.src = previous_url;
console.log(previous_url)
});
}
};
}
思路:
[1]用new image获得图片原始尺寸并记录,用记录中的原始尺寸生成等大的画布。
【注:】所有后续操作均执行在image对象的onload时期。
[2]用XHR来获得图片的base64保存在reader对象的e.target.result中。
【注:】这个base64用在后面创建的img的dom对象赋值src的位置,规避“Tainted canvases may not be exported”的问题。
[3]创建一个img的dom对象接收上面的base64,在这个img的dom的onload阶段使用ctx.drawImage将其绘制于之前与原图等大画布的上下文中。
[4]绘制水印并通过toBlob得到新图片的url
rotate实际是旋转的整个画布,与其算出每次倾斜后的坐标,不如绘制文字时就已经绘制在可视范围外即一个更大的假想画布上,旋转这个假想画布就会使水印也能充满可视画布的边缘了。
[5]用canvas.toBlob将最终的画布输出成blob,通过URL.createObjectURL生成可以被img的src直接使用的url