水印能够很好的保护知识产权。公司的内部资料,往往会加上水印。本文介绍在前端实现水印的一些方法。

明水印

明水印指肉眼看得到的水印。

做明水印,就是将水印内容的元素覆盖在目标元素上面。因为水印元素盖住了目标元素,因此目标元素的点击等事件也不会被触发。在水印元素上设置如下的样式,可以解决这个问题:

  1. .water-mark {
  2. pointer-events: none;
  3. }

水印的内容,用 div, canvas 和 svg 都不难实现。这篇文章:从破解某设计网站谈前端水印(详细教程) 有详细的实现代码。

去掉这样的水印很容易。打开控制台,删掉水印元素就行了。要防护这种情况。我们需要监听水印元素的状态,被删除或修改后,就重新生成一个。JS 有个方法叫 MutationObserver,能够监控元素的改动。实现代码:

  1. // 观察器的配置(需要观察什么变动)
  2. const config = {
  3. attributes: true,
  4. childList: true,
  5. subtree: true
  6. };
  7. const callback = function (mutationsList, observer) {
  8. for (let mutation of mutationsList) {
  9. // 水印被删除了
  10. mutation.removedNodes.forEach(function (item) {
  11. if (item === watermarkElem) {
  12. // 重新创建水印
  13. }
  14. });
  15. // 水印被修改了
  16. if (mutation.type === 'attributes' && mutation.target === watermarkElem) {
  17. // 重新创建水印
  18. }
  19. }
  20. };
  21. // 创建一个观察器实例并传入回调函数
  22. const observer = new MutationObserver(callback);
  23. // 以上述配置开始观察目标节点
  24. observer.observe(document.body, config);

暗水印

暗水印指肉眼看不到的水印。

暗水印的生成方式有很多,通常稍微修改像素点的颜色值。图片的每个像素点的颜色值都是由 RGB 三种元素构成。当我们修改其中的一个分量,人的肉眼是很难看出其中的变化。

加水印的过程,就是改图片像素的过程:

  1. const img = new Image();
  2. const originalData;
  3. img.onload = function() {
  4. ctx.drawImage(img, 0, 0);
  5. // 获取指定区域的canvas像素信息
  6. originalData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
  7. // 加水印 算法
  8. const newData = addWatermark(originalData)
  9. // 生成加过水印的图像
  10. ctx.putImageData(newData)
  11. };
  12. img.src = 'xiaolan.png';

加水印的算法有点复杂,有 DWT、DCT 和 FFT等算法。

读取水印的过程,是上面操作的逆过程。

觉得本文对你有帮助,点个赞,分享给需要的小伙伴吧~

参考文档