惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
雷峰网
雷峰网
V
Visual Studio Blog
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
IT之家
IT之家
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
月光博客
月光博客
A
About on SuperTechFans
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
J
Java Code Geeks
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale

博客园 - 程序员李铁牛

赛事报名系统开发:角色与权限体系设计 赛事系统报名接龙高并发技术细节处理浅析 档案数字化研发手记:PDF合并内存溢出踩坑 纸质档案数字化管理系统研发手记:法院诉讼档案单套制落地案例复盘——从纸质卷宗到电子卷宗 档案数字化管理系统开发手记:人事档案专项审核与数字化的系统支撑——"凡提必审"下的技术要点 档案数字化研发手记:我们的技术栈选择——档案系统前后端选型理由(含一次"炫技"的教训) 社群团购系统开发分享——工程化(下):资金支付测试策略——资金模块 100% 覆盖,其他 60% 就够 社群团购系统类快团团源码开发——工程化(上):一套让 5 人小团队不出事故的开发规范 社群团购类快团团系统开发——RBAC 权限设计源码分析:当一个微信号有 4 种身份时怎么办 社群团购系统类快团团模式开发——微信小程序登录:code2Session 之后还有 5 件事要做 数字档案管理系统化研发手记:医院病历档案数字化——合规、病案首页 OCR 与调阅提速 数字档案系统研发手记:批量扫描任务调度——TWAIN/SANE 采集驱动的封装实践 档案数字化系统研发源码手记:置信度过滤——把 97% 识别率变成真正可交付的成果 档案数字化开发实例手记:盖章遮挡文字识别恢复 景区运营预约系统开发:景区会员体系怎么搭?3级会员模型+积分玩法 景区门票预约系统全渠道平台库存数据同步技术处理方式 系统宕机了怎么办?景区票务系统应急预案模板 景区门票预约系统开发:接入AI预测客流设计思路分析 景区预约系统开发总结:门票分时预约设计原理和落地方法 设备运维管理系统开发实战:用规则引擎实现可配置的设备告警策略自研轻量引擎 vs Drools 落地对比 设备维修保养系统预测性维护不用深度学习?设备健康度评分的务实实现方案 档案数字化管理系统研发手记:档案权限模型——全宗-门类-案卷-文件四级控制的设计与实践 景区票务系统开发实例分析:上云还是本地部署?6个维度判断 档案数字化系统源码研发手记:老旧档案去污点——中值滤波与 inpainting 效果对比 一物一码防伪溯源系统开发全栈源码串联一次扫码的完整链路追踪代码走读 景区门票预约系统票务系统的6个核心模块 景区上线门票预约系统的5个常见翻车点 景区门票预约系统之人脸识别 vs 身份证核验 vs 扫码入园,哪种最适合你? 景区门票预约系统开发深度解析之定价策略功能设计 景区门票预约系统开发深度解析
档案管理信息化系统研发手记:数字水印方案对比——可见水印 vs...
程序员李铁牛 · 2026-08-31 · via 博客园 - 程序员李铁牛

一、档案借阅的最大风险:截图外泄

档案在线借阅的普及带来一个安全难题:用户有权限看,但可以截图/拍照外泄。审批流程管得住"谁能看",管不住"看的人把内容带出去"。

02-挂接率验收报表

水印是防外泄的核心手段,分两大类:

  • 可见水印:肉眼能看到的文字/图案("张三 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)

关键设计点

  1. 水印内容要有"可追责"信息:借阅人、时间、IP、借阅单号——出事后能查到是谁泄露的;
  2. 铺满 or 局部:整页平铺(防裁切)成本高,常用"四角 + 对角"多位置,保证截图必有水印;
  3. 防裁剪:水印要"裁掉一块图,总有一角带水印"——所以四角都放,中间对角再放一条;
  4. 透明度与可读性平衡:太淡挡不住截图者修图,太浓影响阅读——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')

(示意代码,生产实现要处理分块、误差补偿、抗攻击,发布前建议替换为实际方案或标注示意。)

关键设计点

  1. 鲁棒性 vs 隐蔽性平衡:嵌入强度越大越抗攻击但越可见;档案场景要"看不到且扛得住二次压缩/截图";
  2. 攻击对抗:截图、缩放、JPEG 重压缩都会破坏水印——DCT 中频系数是对抗这些的最优平衡点;
  3. 提取需要"密钥/原图":盲水印分"盲提取(不需要原图)"和"非盲提取(需要原图)"——取证时通常有原图,非盲即可,实现更简单鲁棒;
  4. 先加水印后压缩:水印要在最终压缩前嵌入,压缩后再嵌会被压没。

四、实测对比(档案扫描件,JPEG 重压缩 + 截图场景)

方案 隐蔽性(视觉) 抗 JPEG 压缩 抗截图裁剪 提取成功率 实现成本
可见水印(四角+对角) 差(明显) 不影响 中(裁掉可能丢) 取证靠肉眼
LSB 盲水印 差(压缩即毁)
DCT 频域盲水印 中(低强度压缩存活)
深度学习水印

(数据为经验性评估,发布前建议补充你们自己的实测数据。)

五、我们的生产组合方案

借阅在线预览 → 叠加"可见水印"(用户可感知,威慑)
             + 嵌入"盲水印"(用户无感知,取证)
             → 双保险

为什么组合

  1. 可见水印负责"威慑":用户看到自己的名字就不敢截图外传,90% 的泄露在源头被拦住;
  2. 盲水印负责"取证":真有人截图外泄(甚至裁掉可见水印),提取盲水印能定位到人——让"修掉水印"变得无意义
  3. 可见水印挡不住的"技术高手",盲水印能治。

部署要点

  • 水印在"出图"时动态叠加(预览接口返回时),不污染存储的原始档案(原始件永远是干净的,合规);
  • 水印参数(借阅人、时间、单号)从借阅会话取,服务端生成,防伪造
  • 盲水印提取工具只有管理员/审计员可用,提取结果作为处置证据。

六、踩坑记录

坑 1:水印盖住了关键内容。 可见水印压住了档号、落款等关键区域,用户投诉"看不清"。解法:水印位置避开顶部/底部关键区(档号、标题、日期带),或做成"斜向铺满"(每条水印半透明、间距大,不遮挡特定位置)。

坑 2:盲水印嵌完文件变大 + 花屏。 嵌入强度过大,图像出现可见噪点(花屏),且压缩后体积变大。解法:嵌入强度自适应(内容复杂区域强度小),嵌入后人工目检。

坑 3:截图软件直接绕过在线预览。 有用户用浏览器开发者工具直接拉原图接口,绕过水印层。教训:原图接口必须鉴权 + 只能走带水印的出图通道,不允许直出原图。

坑 4:提取失败追责扯皮。 水印提取失败(截图修得太狠),无法证明泄露者。解法:可见水印 + 盲水印双轨,可见水印已留证据;盲水印提取失败也有"该图经过二次处理"的结论——都能支撑处置。

七、小结

  • 可见水印负责威慑、盲水印负责取证,组合使用是档案借阅防泄露的生产标准;
  • 可见水印:多位置铺放 + 可追责信息 + 避开关键区;
  • 盲水印:DCT 频域比 LSB 靠谱(抗压缩),深度学习水印是上限;
  • 水印在出图时动态叠加,不污染原始档案;
  • 原图接口必须鉴权,只走带水印的出图通道。