这个页面的代码没跑起来。

直接从文件夹里打开 index.html,浏览器会拦下 JavaScript 模块,于是你选好要读的那张图之后,页面不会有任何反应。改用 http 把这个文件夹提供出去:

powershell -ExecutionPolicy Bypass -File serve.ps1

然后打开 http://localhost:8080/。

二维码与条形码识读|从图片或摄像头扫二维码

把摄像头对准码,或者把拍下来的图丢进来。读这件事只发生在这里,别处都没有。

语言: 简体中文
查看源码
你的图片和图片里的码在浏览器里处理,无须上传处理。

读一个码是对像素做算术,而像素本来就在这里。找到符号、把拍摄角度校正回来、把掩码解掉、用里德-所罗门把损坏的地方补上、再把比特读回来,这些全都发生在这一页里两千来行你能读的 JavaScript 中。摄像头是同一个承诺,不是它的例外:一帧画面以像素的形式进到这个标签页,被看一眼,然后就没了。什么都不录,什么都不留,而且这一页压根就没有任何能把东西送出去的网络功能。

实时检查: 检查中…

离线: 检查中…

你不用信我们这张嘴。打开开发者工具,盯着“网络”面板,开着摄像头去扫一个码。没有哪一条请求带走过一帧画面,也没有带走过码里的一个字。或者干脆断网,照样把码读出来。

1 把码给它看

一张照片、一张截图,或者摄像头。不管你选哪个,图片都在这里读,在这一页里,在你自己的机器上——什么都不上传,摄像头的一帧是被看一眼就扔掉,不是被录下来。

你也可以用 Ctrl+V 直接把图片粘进来——屏幕上已经有的那个码,截个图是最快的路子。

2 里面写了什么

给你看,但从不替你打开。印出来的码是一个谁也读不出来的地址,而这正是在它上面贴一张贴纸对某些人划得来的原因——所以整串字符都摆在这里给你看,你真正会落到的主机被单独拎出来放一行。

以 Markdown 查看

怎样不上传图片就读出二维码

  1. 把图给它。把照片或截图拖到那个框上,或者直接粘贴一张,或者按摄像头那个按钮。一次好几张也行,每张各读各的,各有各的答案。已经在你屏幕上的码,截个图是最快也最靠谱的路子,因为那里既没有镜头,也没有角度,更没有光。
  2. 让整个符号连同留白一起进画面。码周围那圈白是码的一部分:识读器就是靠它知道符号到哪儿为止的。裁到方块边缘的照片,是一个码读不出来的最常见原因,没有之一。让码占到画面一半左右差不多正好;再靠近,四个角就跑到画面外面去了。
  3. 在决定任何事情之前,先把地址读一遍。去扫海报、停车缴费机或者信件上的码,图的就是弄清楚它通向哪里;而这恰恰是手机摄像头真正不让你做的那一件事。这里主机单独占一行。要不是你预想中的那个名字,你要的东西其实已经到手了,也就没什么好打开的了。
  4. 把提示当回事,尤其是那些不响的。光秃秃的 http:// 地址、用看起来不是那套文字的字母写的名字、短链接服务,或者地址里 @ 前面的任何东西——每一样都会在它出现的地方被点名。它们单拿出来谁也证明不了什么,但在你过去之前,每一样都值十秒钟。
  5. 读不出来,先改光,别先改别的。几乎所有失败都是阈值的问题:横在中间的反光、压在一角的阴影,或者以某个恰好把背光收进来的角度拍下的屏幕。挪个位置让反光别落在码上,或者把摄像头的灯打开。还不行就正对着拍一张平的照片,把那张丢进来——一张静止的图会得到比实时画面细致得多的搜索。
  6. 答案看着不对劲,就看看采样出来的那张图。把“这一个是怎么读出来的”展开,看那个小格子。它是这一页认为这个码长什么样,从采到的模块重新画回去的结果。一个把符号读错、又修补成了某种像模像样东西的识读器,只会在那里露出马脚,别处都不会。

说得更细的版本

怎么做一个二维码,并证明它扫得出来 生成二维码,再用同一个网站的识别器验证:一字不差的内容、真正的链接,按印刷尺寸、用一张照片,在批量印刷之前。全在浏览器里,什么都不上传。

常见问题

图片会被上传到什么地方去吗?

不会,从图里读出来的东西也不会。图片在这一页的画布上解码,然后就在那里被读,用的是这个站点提供的 JavaScript。这个工具压根没有任何网络功能——它从不去取东西,也从不发东西——而这一页的 Content-Security-Policy 把它可以联系的地址一个不落地写了出来,其中没有一个是我们的。最简单的证明就是断网:它照样能用。

摄像头会录下什么吗?

不会。摄像头的一帧以像素的形式进到这个标签页,画到画布上,被看一眼,大约十分之一秒后就被下一帧盖掉。没有东西写到硬盘上,也没有东西留下来。你一按停止,流就断了;标签页退到后台时会断,你离开这一页时也会断。而值得信的指示是你摄像头上的那盏灯,因为没有哪一个网页能把它关掉。

为什么它只把链接给我看,不直接打开?

因为有用的正是这一步。二维码是一个你读不出来的地址,贴在停车缴费机码上的那张贴纸之所以管用,靠的就是这一点:等你知道它去了哪儿,你已经在那儿了。这里整串字符原样印出来,主机被拎出来单独占一行,打开是另一个按钮,读完之后你自己按。这是多一次点击,而这一次点击正是这个格式一直都缺的。

它能读什么?

二维码从版本 1 到 40 全都能读,四个纠错等级都能读,数字、字母数字、字节和汉字模式都能读,ECI 字符集和属于一组连拼符号的码会被报出来,而不是悄悄扔掉。条纹那一边:EAN-13、EAN-8、UPC-A、UPC-E、ITF-14、交叉二五码、Code 128 和 Code 39。Data Matrix、PDF417、Aztec 和 MaxiCode 它不读。

我的码读不出来,是哪里不对?

十次里有九次是三件事里的一件。白色留白被裁掉了,而识读器要靠它知道符号到哪儿为止。码有一块被反光或阴影盖住了,于是没有哪个阈值能把深色方块和浅色方块分开。或者码在画面里太小,模块只有一两个像素宽。换个光,让码占到画面一半左右,正对着拍而不是斜着拍。

破损的或被挡住一部分的码,它能读吗?

有时可以。Reed-Solomon 纠错可在符号的纠错能力内恢复损坏的码字。H 级约 30% 指全部码字的比例,并非任意模块或图像面积的 30%;定位图形受损可能导致完全无法识别。结果下方的修复数表示本读取器实际纠正的数量。DENSO 解释了各级别。

为什么它说不出一个 bit.ly 链接通向哪里?

因为要弄清楚就得去问 bit.ly,而那是一次网络请求。这一页别的所有说法都立在“这里没有任何代码会去联系任何东西”上面,为这件事偷偷开个口子,比这个答案本身亏得多。所以短链接服务的名字会被点出来,它藏起来的东西则老老实实地留作未知。你真想解开,就把它粘到一个愿意去问的地方。

扫二维码这件事本身安全吗?

扫是安全的。照着它做才是风险,而且是真实的风险:贴在真码上面的假码,在停车缴费机上、在餐馆桌上、在快递取件单上,已经常见到有了专门的名字。它们之所以管用,是因为没人能靠看把一个码读出来。读它但不打开它——也就是这一页在做的事——把那点便宜整个拿掉了,而看一眼主机所花的十秒钟就是全部的防守。

每个结果下面那个小格子是什么?

是这一页真正从你的图里采到的那些模块,按一个模块一格重新画出来的。它放在那里,是为了让读出来的结果可以用眼睛核对,而不是只能相信:要是那个格子看起来就是你拍的那个码,上面的答案就来自正确的像素。几乎没有识读器给你看这个,而这正是“能查的工具”和“只能信的工具”之间的差别。

一张图里有好几个码,它都能读吗?

眼下一张图一个。一次拖进来好几张,每张各读各的;开着摄像头慢慢移,它会一个接一个地读,把每个还没见过的新码留下来。一张照片里拍下一整页码,那是该去裁图,或者把摄像头一个一个对过去的场合。

为什么它给我的条形码起了个跟我要的不一样的名字?

因为条形码不带着自己的名字走。UPC-A 就是首位为零的 EAN-13,ITF-14 就是十四位、校验位对得上的交叉二五码,而 Code 128 在数字模式下不像别的任何东西。这一页报的是那些条纹说了什么,加上校验位确认了什么——符号自己知道的也就这么多。

断网能用吗?

能。把页面加载一次,然后断网,它照样能用,摄像头也一样。这同时也是证明什么都没被上传的最简单办法:一个要把你的图送出去解码的识读器,在你拔线的那一刻就停了。