Happy Face LogoHAPPY IMG
内容
指南最近审核: 2026-04-22

如何在浏览器里自动检测二维码、签名和车牌

一份浏览器端实现指南,讲清楚怎样把 BarcodeDetector、基于 OCR 的启发式规则和像素分析组合起来,生成可复查的隐私遮挡区域。

自动隐私清理通常不是靠一个检测器完成的。二维码、签名和车牌虽然在产品层面都属于“敏感区域”,但从实现角度看,它们并不是同一种问题,所以更实用的浏览器端工具往往会组合多种策略,而不是强行全部走一条 OCR 流程。

这也是 二维码打码签名打码工具车牌模糊 这类工具背后更合理的实现方式。这里真正有意思的点在于,不同目标需要依赖不同信号。

一条通用流水线不够用

从产品角度看,这三类目标都只是需要生成敏感区域。但从技术角度看,它们差别很大:

  • 二维码和条码是机器可读符号,浏览器本身就可能提供检测能力。
  • 车牌更适合走 OCR 加启发式过滤。
  • 签名更接近图像形状检测,而不是文本识别。

如果想用一次通用 OCR 解决这三类问题,结果通常不会太理想。

二维码和条码:浏览器已经会的事就直接用

对于二维码和条码,最干净的实现方式通常是优先使用 BarcodeDetector,前提是当前浏览器支持它。

const detector = new BarcodeDetector({
  formats: ["qr_code", "code_128", "ean_13", "pdf417"],
});

const results = await detector.detect(source);

每个结果都会返回一个 bounding box,再经过适当 padding 就可以变成更安全的遮挡区域。这样就能用浏览器原生能力处理机器可读符号,而不必从零手写一套视觉检测。

这里真正重要的产品决策是 fallback。假如 BarcodeDetector 不可用,界面应该明确告诉用户,而不是默默假装“没有检测到二维码”。

车牌:OCR 加过滤规则,比原始 OCR 更实用

车牌本质上是文本,但它不是普通文本。这个项目里的做法,是先从 OCR block 里拿候选文本,再叠加一组专门针对车牌的过滤条件:

  • 先把文本标准化成大写字母和数字
  • 必须同时包含字母和数字
  • 过滤掉长度明显不合理的结果
  • 过滤掉长宽比不合理的区域
  • 忽略出现在图像过高位置的文本

这种模式很实用,因为 OCR 负责提供候选内容,而启发式规则负责去掉大量原本会变成误判的噪声。

签名:把它当成图像连通区域,而不是单词

手写签名正好相反。OCR 在这里往往不够可靠,所以这个代码里的检测路径采用的是基于缩放 canvas 的像素分析:

const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const threshold = estimateSignatureThreshold(data);

然后算法会遍历连通的深色像素区域,再根据宽度、高度、填充率和位置筛掉不合理候选,只保留更像签名的区域。

这也说明一个现实:隐私工具经常需要很窄、很具体的启发式规则,而不是一个包打天下的统一模型。

检测后还需要 padding、合并和去重

检测出候选区域,只完成了一半工作。后面还必须处理这些事情:

  • 给边界加 padding,确保敏感内容被完整覆盖
  • 如果一个签名或码被拆成多段,要合并相邻区域
  • 如果结果重叠,要做去重

如果跳过这一步,编辑器里就会出现一堆碎片化的小框,用户很难信任结果。

把检测结果变成可编辑叠加层

一个真正可用的产品,不应该把模糊或打码结果悄悄直接应用到图片上,而应该把这些候选区域作为自动生成的叠加层插入编辑器,交给用户复查。

这样即使不同检测器的内部原理完全不同,最终在交互层也可以统一成同一种模型。

混合检测器比较合理的架构

更实用的边界通常是:

  • 一个统一的编辑器表面
  • 多个独立的检测函数
  • 一种统一的区域数据结构
  • 导出前统一走一次复查

这样无论接入的是 OCR、条码 API,还是像素级启发式规则,都不需要每加一种检测器就重做一套编辑逻辑。

真正让它有用的点

这里最重要的技术经验其实很简单:隐私检测的效果,往往来自于你不再试图寻找一个万能检测器。浏览器端工具只有在不同目标类型用上合适的信号时,才会真正变得可靠。

Happy Face Mascot