二维码 非常实用,但从来没人夸过它好看。
通常想让它别那么像数字方格纸,人们会在中间贴个 logo、把边角修圆、改改颜色,然后祈祷手机还能读出来。
但有个 抖动二维码生成器 能把一张真实照片本身变成二维码,成品看起来出奇地像老式黑白电脑图形,却仍包含可扫描的数据。该项目近期在网上走红,8 月 24 日还被 Adafruit 专题报道。
不过,这可不是在半透明二维码后面贴张图那么简单。这里头有巧妙的图像处理。
二维码比你以为的更有余量
二维码是黑白模块组成的网格,但网格里不是每个部分作用都相同。大方块等固定图案帮手机定位、定向、识别码。其余模块承载编码数据与相关信息。一旦扫描器知道网格在哪,它主要关心在网格内采样合适的点。这就打开了一种可能:让每个模块里真正的数据点相对小一点,再用周围像素干点别的。
如果你用过古董 Mac、用单色激光打印机印过东西,或在 1-bit 显示器上玩过游戏,你就见过抖动(dithering)。假设你只有黑白像素却想显示灰色——你没法真的让一个像素变灰,于是就把黑白像素排成某种图案,让眼睛解读成不同深浅。
巧妙之处
记得那些必须包含二维码数据的中心像素吗?它们才不在乎你的照片长什么样。你的图可能说某个像素应该几乎全黑,而二维码说“不,这个必须是白”。
这会在整张图里制造看似随机的椒盐噪声。该生成器用两轮误差扩散来处理:第一轮先把二维码数据像素放到该在的位置,产生的亮度误差散布到周围像素;第二轮更常规,把图的其余部分转成黑白。结果干净得多,因为图像实际上补偿了二维码强行让它“错”的那些像素。这是两项完全不同技术协作的绝佳例子:纠错让二维码可读,误差扩散让画面可辨。
下面是一些例子。比如我们自己的 Jon Biloh,标注了 lowendbox.com:
或者 LowEndTalk 那位“臭名昭著”的 Calin,用了较低分辨率设置:
自己试试!但先别印 5 万张传单
生成器在此:https://www.andrewt.net/dithered-qr-codes/index.html
不过这一切有个坑,或者说至少一个小提醒。普通二维码刻意做得丑且冗余,是因为它们本就为了糟糕条件下也能用——皱纸、差打印机、弱光、划痕招牌、手抖的相机、别扭的角度,都是这格式设计来扛的。你为美观牺牲的每一分冗余,都在压缩容错空间。
这些艺术二维码在大幅面显示屏和海报上表现不错,但从笔记本屏幕扫得完美,一旦被打印、折叠、光线昏暗、对着老手机摄像头,就可能失败。生成器产出的图还缺少通常四周的静默区,真正部署时你要自己加上。
尽管如此,作为黑客技巧,这一招相当出色。
