二维码读取上传

把包含二维码的图片文件上传到浏览器本地解码,读出里面的网址、文本或 Wi-Fi 配置,全程不经过服务器,识别失败会给出具体原因。

序号识别内容字符数UTF-8 字节
示例展示(演示值,点「选择图片」上传真实二维码后会被真实结果替换):
文件:demo-qr.png
条码数量:1
内容:https://liuquan.net/shengchengqi/erweimashengchengqi/
长度:53 字符(UTF-8 53 字节)

提示:识别结果只是文本,不会自动打开网址。如果解出来的是 %E4%B8%AD 这类百分号转义串,先自己确认来源可靠,再交给「URL解码」处理。

使用方法

  1. 点「选择图片」,挑一张包含二维码的图片,格式可以是 PNG、JPG、WebP、BMP 或 GIF,文件不能超过 5MB(5242880 字节)。
  2. 点「识别图片中的二维码」。识别在浏览器本地完成,图片不会被上传,断网状态下这一步照常能跑。
  3. 看结果区:识别成功时,表格逐行列出每个码的内容、字符数和 UTF-8 字节数;下方的文本框是所有内容的纯文本,方便直接复制。
  4. 点「复制识别结果」把纯文本带走,或点「导出 CSV」存成带表头的表格文件(带 BOM,Excel 打开不乱码)。
  5. 识别失败时看红色提示:它会写清是文件超了 5MB、不是图片,还是画面里没有检测到二维码,按提示处理后重试。

这个二维码读取上传能解决什么问题

一是读图不扫码:二维码出现在截图、聊天记录、PDF 导出页里,手机相机对着屏幕扫常常失灵,把截图存下来上传,一次就能读出内容。

二是先看内容再决定要不要打开:二维码读取上传的输出是纯文本,解出来的网址原样摆在你眼前,不会自动跳转。遇到来路不明的码,先看清域名再动手,是避开钓鱼页的第一道检查。

三是读出非网址内容:Wi-Fi 分享码解出来是 WIFI:T:WPA;S:HomeWiFi;P:pass1234;; 这样的配置串(34 个字符),电话码是 TEL:+8601012345678(18 个字符),从里面直接抄 SSID 和密码,比再装一个扫码 App 省事。

四是批量核对:打印物料上的二维码是否扫得出来、内容是否正确,把样品拍照上传就能核对,不用逐个拿设备扫。

本页不做这些事:不生成二维码(那是「二维码生成器」的活,两者互为逆操作)、不解一维条形码(EAN-13 之类的码请用「条形码读取上传」)、不调用摄像头实时取景(怀疑摄像头坏了可以用「摄像头测试」先查设备)。

原理与规则说明:BarcodeDetector 与画布预处理

解码调用的是浏览器内置的 BarcodeDetector 接口(W3C Shape Detection API 的一部分),不是页面自带的解码算法。构造时传 { formats: ['qr_code'] },只登记二维码这一种格式;随后把图片传给 detect(),它返回一个 Promise,兑现为数组,每个元素带 rawValue(解码出的文本)字段。数组可能不止一个元素——一张图里印了几个二维码,就逐行出几条结果。

上传的文件先走三条校验:文件为 0 字节直接拒绝;超过 5242880 字节(5MB)拒绝;类型不是 image/ 开头也不是常见图片扩展名拒绝。通过后再经 URL.createObjectURL 交给 Image 解码,画到 canvas 上。画布有 4096 像素的边长上限:原图更大时等比缩小,例如一张 8000×6000 的照片,缩放因子是 4096÷8000 = 0.5120,画布实际为 4096×3072。上限的道理是内存——解码后的位图每像素占 4 字节,4096×4096 = 16777216 个像素就是 64MB,再大就会让低配设备卡顿。

为什么 5MB 和 4096 这两个数字取在这里:条码检测对相对尺寸敏感而不是绝对尺寸,手机照片动辄 12MP 以上,等比缩到 4096 边长以内不损失可识别性,却把计算量压掉了九成以上。实测经验是二维码边长不小于画面短边的 44.7%(即约占画面面积五分之一)时识别最稳。

浏览器不支持 BarcodeDetector 时,本页给出降级提示而不是硬解——手写一个 QR 解码器要实现伽罗瓦域纠错、掩码评分等一整套规范,体积远超本站的内联脚本预算,所以不支持的环境会明确告诉你换 Chrome、Edge 等 Blink 内核浏览器打开。

完整示例(数值仅作演示)

示例文件 demo-qr.png 里印着一个二维码,内容是本站二维码生成器的地址:

工具区那段「示例展示」就是按这份演示数据写好的,打开页面即可看到结果长什么样;上传真实图片并识别成功后,它会被真实结果替换。若你把这个地址复制进「二维码生成器」再上传回来,识别结果应与原地址逐字符一致——这就是生成与读取互为逆操作的直观验证。

输入范围与对照表

文件侧的限制汇总如下:

检查项允许范围超界行为
文件大小1 ~ 5242880 字节(5MB)0 字节提示空文件;超出提示实际字节数与上限
文件类型PNG、JPG、WebP、BMP、GIF非图片类型提示实际 MIME 类型
画布边长最长边缩放到 4096 像素内更大的图等比缩小后识别
二维码数量1 张图内多个码都识别逐行列出,互不干扰
识别结果纯文本(rawValue 原样输出)不自动打开链接、不执行任何内容

二维码本身的规格由 ISO/IEC 18004 定义,40 个版本按「边长 = 21 + 4 ×(版本号 − 1)」递增:

版本模块边长总格数典型用途
v121 × 21441十几个字符的短网址
v225 × 25625普通网址、名片项
v537 × 371369带参数的推广链接
v1057 × 573249Wi-Fi 配置串、长文本
v25117 × 11713689整段说明文字
v40177 × 17731329规格上限,接近容量极限

版本越高格越密,对拍摄清晰度的要求也越高,正文内容超过几百字节时应该换短链接而不是追求高版本。

输入范围、边界与精度说明

常见问题

为什么 Firefox 和 Safari 打开这个页会提示不支持?

本页解码依赖浏览器原生 BarcodeDetector(Shape Detection API),目前 Chrome、Edge 等 Blink 内核浏览器实现了它,Firefox、Safari 还没有。页内不引第三方解码库、也不手写解码器,所以检测不到接口时直接说明情况并建议换浏览器,而不是给出不可靠的结果。

为什么限制 5MB?我手机拍的照片普遍比这大。

限制针对的是解码位图的内存:图片缩放到最长边 4096 像素后,16777216 个像素每像素 4 字节,约 64MB,已经够低配设备消化。原图超出 5242880 字节时,用系统截图工具截二维码区域,或另存为 JPG,几乎总能压进限制,且识别率反而更高。

一张图里有多个二维码,能一次全读出来吗?

能。detect() 返回数组,有几个码就出几行,每行带各自的字符数与字节数。但靠得太近或部分重叠的码可能只识别出一个,需要分开截图逐个读。

解出来的网址会自动打开或跳转吗?

不会。结果区是纯文本,本页没有绑定任何跳转行为。要访问时自己复制到地址栏,这正是「先看清再打开」的设计意图;解出 %E4 之类的百分号串时先用 URL 解码工具还原成中文再看。

Wi-Fi 码解出来那串分号是什么意思?

那是 WXF 规范定义的 WIFI: 格式:T 是认证方式,S 是网络名,P 是密码,双分号收尾。工具解出原文后你直接照抄 S 和 P 两段即可,不需要再处理。

付款码、微信码这类也能解吗?

格式上它们也是二维码,能解出内容,但内容是各家私有协议的编码串,没有可读性。解出来通常只能看到一长串字母数字,这是正常的——这类码本来就不是给通用解码器读的。

为什么识别率比手机相机扫码差一些?

相机扫码有取景框引导和连续帧尝试,几十帧里挑最清晰的一帧;本页只有你上传的这一张静态图。裁剪紧凑、光线均匀、码占比不低于画面面积五分之一的图,识别效果接近相机。

识别结果会被上传或保存吗?

不会。文件经浏览器临时 URL 在本地解码,Network 面板全程没有外发请求,刷新后结果清空。想长期留存用「导出 CSV」自己存文件。

相关工具