档案管理信息化系统研发手记:数字水印方案对比——可见水印 vs 盲水印(档案借阅防泄露)
一、档案借阅的最大风险:截图外泄
档案在线借阅的普及带来一个安全难题:用户有权限看,但可以截图/拍照外泄。审批流程管得住"谁能看",管不住"看的人把内容带出去"。

水印是防外泄的核心手段,分两大类:
- 可见水印:肉眼能看到的文字/图案("张三 2026-08-28 借阅");
- 盲水印(隐形水印):肉眼几乎看不到,但能从图像中提取(嵌入编码信息)。
两者不是替代关系,而是组合使用。这篇讲清楚各自的技术方案、适用场景和坑。
二、可见水印:简单、威慑、但有代价
实现方案
from PIL import Image, ImageDraw, ImageFont
def add_visible_watermark(img, text, pos="bottom_right",
font_size=24, opacity=0.6):
"""叠加半透明文字水印(PNG 上做 alpha 叠加)"""
img = img.convert("RGBA")
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
font = ImageFont.truetype("simhei.ttf", font_size)
# 计算位置
if pos == "bottom_right":
x = img.width - len(text) * font_size - 40
y = img.height - font_size - 40
draw.text((x, y), text, fill=(255, 0, 0, int(255 * opacity)), font=font)
return Image.alpha_composite(img, overlay)
关键设计点
- 水印内容要有"可追责"信息:借阅人、时间、IP、借阅单号——出事后能查到是谁泄露的;
- 铺满 or 局部:整页平铺(防裁切)成本高,常用"四角 + 对角"多位置,保证截图必有水印;
- 防裁剪:水印要"裁掉一块图,总有一角带水印"——所以四角都放,中间对角再放一条;
- 透明度与可读性平衡:太淡挡不住截图者修图,太浓影响阅读——0.5~0.7 透明度是经验值。
优点与缺点
- 优点:实现简单、威慑力强(用户看到"张三"的水印就不敢乱传)、取证直接;
- 缺点:影响阅读体验、截图后可用 PS 等工具局部修补(但成本高,威慑已足够)、纯文字水印可被覆盖。
三、盲水印:看不见的证据链
原理简介
盲水印把信息(借阅人 ID、时间戳)编码后嵌入图像的频域/空间域,人眼看不出,但通过提取算法能还原。经典做法:
- LSB(最低有效位)水印:修改像素最低位存储信息——容量大、易被压缩破坏;
- DCT/DWT 频域水印:把信息嵌入变换域系数——抗压缩、抗裁剪,是档案场景更靠谱的选择;
- 深度学习水印(U-Net 编码器/解码器):嵌入更隐蔽、鲁棒性更强,但实现复杂。
# DCT 盲水印(示意:嵌入 -> 提取)
import numpy as np
from scipy.fftpack import dct, idct
def embed_dct_watermark(img_block, bit):
"""把一个 bit 嵌入 8x8 块的 DCT 中频系数"""
dct_block = dct(dct(img_block, axis=0, norm='ortho'), axis=1, norm='ortho')
mid = 4 # 中频系数位置(低频被压缩保留,高频易丢)
# 量化嵌入:把中频系数调到奇偶对应 bit
q = 8 # 量化步长(越大越鲁棒,但越明显)
dct_block[mid, mid] = (abs(dct_block[mid, mid]) // q * q + q // 2) \
* (1 if bit else -1)
return idct(idct(dct_block, axis=0, norm='ortho'), axis=1, norm='ortho')
(示意代码,生产实现要处理分块、误差补偿、抗攻击,发布前建议替换为实际方案或标注示意。)
关键设计点
- 鲁棒性 vs 隐蔽性平衡:嵌入强度越大越抗攻击但越可见;档案场景要"看不到且扛得住二次压缩/截图";
- 攻击对抗:截图、缩放、JPEG 重压缩都会破坏水印——DCT 中频系数是对抗这些的最优平衡点;
- 提取需要"密钥/原图":盲水印分"盲提取(不需要原图)"和"非盲提取(需要原图)"——取证时通常有原图,非盲即可,实现更简单鲁棒;
- 先加水印后压缩:水印要在最终压缩前嵌入,压缩后再嵌会被压没。
四、实测对比(档案扫描件,JPEG 重压缩 + 截图场景)
| 方案 | 隐蔽性(视觉) | 抗 JPEG 压缩 | 抗截图裁剪 | 提取成功率 | 实现成本 |
|---|---|---|---|---|---|
| 可见水印(四角+对角) | 差(明显) | 不影响 | 中(裁掉可能丢) | 取证靠肉眼 | 低 |
| LSB 盲水印 | 好 | 差(压缩即毁) | 差 | 低 | 低 |
| DCT 频域盲水印 | 好 | 中(低强度压缩存活) | 中 | 中 | 中 |
| 深度学习水印 | 好 | 好 | 好 | 高 | 高 |
(数据为经验性评估,发布前建议补充你们自己的实测数据。)
五、我们的生产组合方案
借阅在线预览 → 叠加"可见水印"(用户可感知,威慑)
+ 嵌入"盲水印"(用户无感知,取证)
→ 双保险
为什么组合
- 可见水印负责"威慑":用户看到自己的名字就不敢截图外传,90% 的泄露在源头被拦住;
- 盲水印负责"取证":真有人截图外泄(甚至裁掉可见水印),提取盲水印能定位到人——让"修掉水印"变得无意义;
- 可见水印挡不住的"技术高手",盲水印能治。
部署要点
- 水印在"出图"时动态叠加(预览接口返回时),不污染存储的原始档案(原始件永远是干净的,合规);
- 水印参数(借阅人、时间、单号)从借阅会话取,服务端生成,防伪造;
- 盲水印提取工具只有管理员/审计员可用,提取结果作为处置证据。
六、踩坑记录
坑 1:水印盖住了关键内容。 可见水印压住了档号、落款等关键区域,用户投诉"看不清"。解法:水印位置避开顶部/底部关键区(档号、标题、日期带),或做成"斜向铺满"(每条水印半透明、间距大,不遮挡特定位置)。
坑 2:盲水印嵌完文件变大 + 花屏。 嵌入强度过大,图像出现可见噪点(花屏),且压缩后体积变大。解法:嵌入强度自适应(内容复杂区域强度小),嵌入后人工目检。
坑 3:截图软件直接绕过在线预览。 有用户用浏览器开发者工具直接拉原图接口,绕过水印层。教训:原图接口必须鉴权 + 只能走带水印的出图通道,不允许直出原图。
坑 4:提取失败追责扯皮。 水印提取失败(截图修得太狠),无法证明泄露者。解法:可见水印 + 盲水印双轨,可见水印已留证据;盲水印提取失败也有"该图经过二次处理"的结论——都能支撑处置。
七、小结
- 可见水印负责威慑、盲水印负责取证,组合使用是档案借阅防泄露的生产标准;
- 可见水印:多位置铺放 + 可追责信息 + 避开关键区;
- 盲水印:DCT 频域比 LSB 靠谱(抗压缩),深度学习水印是上限;
- 水印在出图时动态叠加,不污染原始档案;
- 原图接口必须鉴权,只走带水印的出图通道。
微信号:tieniu6636
浙公网安备 33010602011771号