- QRCode.js 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库。
- jimp.js 一个完全用 JavaScript 编写的 Node 图像处理库,零原生依赖。也可用于浏览器端
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jimp/0.9.7/jimp.min.js"></script>
- #qrcode 存放生成的二维码
- #png 存放需要加水印的图片
<input id="text" type="text" value="http://www.baidu.com" style="width:80%" /><br />
<button id="btn" onclick="makeQrcode()">加水印</button>
<div id="qrcode" style="width:100px; height:100px; margin-top:15px; border: 1px solid #ccc;"></div>
<img src="./index.png" style="display: block;" id="png" />
- 使用 QRCodejs 生成二维码。生成的二维码是一段base64编码的字符串。自动设置到#qrcode 容器下img元素的src中
- 监听到#qrcode 容器下img元素的src变化后 使用 jimpjs 图片混合实现水印的添加。
let qw = null;
function makeQrcode() {
const text = document.querySelector('#text').value;
if(!qw){
qw = new QrcodeWatermark("#qrcode", "#png")
}
qw.makeCodeContent(text);
}
class QrcodeWatermark {
waterEl = null;
originImgEl = null;
qrcode = null;
constructor(selector, originSelector, {width = 70, height = 70} = {}){
this.waterEl = document.querySelector(selector);
this.originImgEl = document.querySelector(originSelector);
this.qrcode = new QRCode(this.waterEl, { width, height });
this._observe();
}
_observe(){
const observer = new MutationObserver((mutationsList, observer) => {
const node = mutationsList.find(item => item.target.localName === 'img' && item.attributeName === 'src');
if (!node) {
return;
}
this.merge(node.target.src, this.originImgEl.src);
});
observer.observe(this.waterEl, {
childList: true,
subtree: true,
attributes: true
});
}
makeCodeContent(text) {
this.qrcode.makeCode(text);
}
merge(waterFile, originFile, proportion = 7, marginProportion = 0.06) {
Promise.all([jimp.read(waterFile), jimp.read(originFile)]).then(
([water, origin]) => {
const curProportion = origin.bitmap.width / water.bitmap.width;
water.scale(curProportion / proportion);
const right = origin.bitmap.width * marginProportion;
const bottom = origin.bitmap.height * marginProportion;
const x = origin.bitmap.width - right - water.bitmap.width;
const y = origin.bitmap.height - bottom - water.bitmap.height;
origin.composite(water, x, y, {
mode: jimp.BLEND_SOURCE_OVER,
opacitySource: 1,
});
origin.getBase64Async(Jimp.AUTO).then((base64Url) => {
this.originImgEl.src = base64Url;
});
}
).catch(e => {
});
}
}