给 Web 端网站添加水印
背景
前段时间在公司遇到有人通过后台管理系统通过截图的方式泄漏数据。于是提出了一个需求,给后台网站添加水印的同时希望用户看不见,但是我们能通过截屏的图片解析出水印的内容,这样就可以知道是会泄漏的。
经过调研
在 web 端加水印的方式一般都是通过 canvas 绘制水印,然后通过 css 的 background
属性设置背景图片,并且平铺开来。
我们可以通过下面的 JavaScript 代码来实现一个简单的水印,代码如下:
function watermark({ width = 100, height = 100, content, debug = false }) {
// 通过 canvas 绘制水印内容
const createWaterMark = content => {
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
ctx.rotate(-10 * Math.PI / 180)
ctx.font = 'bold 24px serif'
ctx.fillStyle = debug ? 'rgba(255,0,0,1)' : 'rgba(255,0,0,0.005)'
const lines = content.split(',')
for (const line of lines) {
ctx.fillText(line, 0, 50)
ctx.translate(0, 30)
}
return canvas.toDataURL()
}
// 创建一个 `div#watermark` 元素并添加到 `body` 上
let watermarkDiv = document.querySelector('#watermark')
if (!watermarkDiv) watermarkDiv = document.createElement('div')
const base64Url = `url(${createWaterMark(content)})`
watermarkDiv.setAttribute('id', 'watermark')
watermarkDiv.setAttribute('style', `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999999999;
pointer-events: none;
background-repeat: repeat;
background-image: ${base64Url};
`)
document.body.appendChild(watermarkDiv)
}
本页面已经加载了此 watermark
方法
watermark({ content: 'yuler', debug: true })
可以看见水印,然后让我们运行透明模式
watermark({ content: 'yuler' })
可以看见透明样式的水印的样式,就无法通过肉眼看见水印。
因为给设置一个透明度很高的水印,这样用户就可以看不见,但是通过截屏的方式水印依然在上面。 然后我通过 PhotoShop 调节曲线,就可以看到水印的内容。
这里我保存好了,一个曲线配置 watermark.acv,我们可以通过这个曲线配置来显示出水印
通过 PhotoShop 工具
- 打开 photopea 加载此曲线
- 上传带有透明水印的图片,
Command + m
打开曲线配置后,在 Preset 中选择watermark
曲线配置
通过 ffmpeg
同时可以通过 ffmpeg
来实现 PhotoShop 调节图片曲线的功能。
ffmpeg -i input.png -vf "curves=psfile=watermark.acv:interp=pchip" -update 1 output.png
输出结果
结论
既然可以通过 ffmpeg
命令行来将透明水印显示出来,那么我就用 Rails 写了个简单的 web 应用。仓库地址:yuler/watermark
稍后会部署到 watermark.yuler.dev 域名下