Android zxing库生成的QR码无法被大多数QR码扫描器扫描

3
我发布这篇文章来回答自己的问题(在此宣传一下,以防其他人也遇到了这个问题)。
我正在使用ZXing的Android库生成QR码。QR码可以正常生成,我也能够显示它(手动呈现出来使用QRCode.getMatrix().getArray())。然而,生成的QR码不能被市面上大部分的QR码读取器扫描,包括ZXing的扫描器本身!
此外,每当我为Encoder设置错误校正级别时,它都会忽略它并使用某个随机级别进行编码(通常是级别Q)。
我使用以下代码生成QR码:
    QRCode code;
try { code = Encoder.encode("...QRCODEDATA...", ErrorCorrectionLevel.L); } catch(WriterException ex) { log("无法获取QR码"); return null; }
然后,在获得QRCode对象之后,我像这样绘制位图:

byte[][] bitArray = qrCode.getMatrix().getArray();

        if(bitArray == null || bitArray.length < 1)
            return null;

        for(int x = 0;x < bitArray.length;x++)
        {
            for(int y = 0;y < bitArray[x].length;y++)
            {
                if(bitArray[x][y] == 0)
                    bitmapDrawCell(x,y,WHITE);
                else
                    bitmapDrawCell(x,y,BLACK);
            }
        }

就是我最终得到的结果。


看起来没问题,但无法扫描。少数QR码扫描器仍然可以扫描它,但大多数不能。发生了什么事?


3
这个问题的答案: 二维码实际上是翻转的。虽然 ZXing 的文档没有解释如何索引 qrCode.getMatrix().getArray() 返回的数组,但它假设您将其索引为[y][x],然后在(x,y)处绘制该单元格。但问题中发布的代码将数组索引为[x][y],这会沿着 Y=X 线翻转图像。生成的二维码似乎是合法的,但只有“智能”扫描仪才能检测到这种翻转并进行扫描。 (纠错级别位也在相反的角落。) - Alex
是的,我用我的扫描仪尝试过了。原始版本会出现无法恢复的错误,而翻转后的版本可以无错误地读取。您应该将其作为答案并接受它,以便问题不再开放。 - Henry
@Henry:我会在获得足够的声望后将其作为正式答案发布(stackoverflow对新用户非常严格)。 - Alex
2个回答

3
这个问题的解决方法是:QR码实际上是翻转的。虽然ZXing文档没有说明如何索引qrCode.getMatrix().getArray()返回的数组,但它假定您将其索引为[y][x],然后在(x,y)处绘制该单元格。问题中发布的代码将数组索引为[x][y],这会沿着Y=X线翻转图像。 生成的QR码似乎是合法的,但只有“智能”扫描仪才能检测到这种翻转并进行扫描。
错误校正级别位也在相反角上,因此如果您要手动验证(查看图像右下角的几个位),那么库似乎会忽略错误校正设置。 flipped QR code

1
是的,虽然我猜你应该使用获取方法而不是直接访问数组,因为获取方法更清楚地表达了x和y之间的关系。这是一个来自C++的旧类,其表示是行优先(row-major),当我们想到条形码的行时,它实际上是直观的,但在对其进行索引时却需要'翻转'。我会给它加上文档说明,尽管这个方法可能只是被弃用。 - Sean Owen
感谢您的回复,Sean。目前我更希望它只是被记录下来。出于效率考虑,我喜欢将整个事物表示为一个数组的想法。在我的情况下这并不重要,但对于一个大的QR码,也许使用数组会更快?我不是Java分析专家,所以我可能错了。 - Alex
JIT会在运行时快速地内联这样一个简单的getter。即使没有它,方法调用也非常小,即使是一个200x200的大型代码在每个位置被访问数千次,也只有数百万个方法调用...谈论毫秒级别的时间。 - Sean Owen

1

也许并不是你问题的答案,但你可以考虑使用谷歌的QR码生成器。我使用过它,非常简单易用。谷歌QR码


我曾考虑过这个选项,但问题在于,谷歌的在线QR码生成器需要进行网络调用,而我正在编写的应用程序在生成QR码时不能使用互联网(可以将其视为登上地铁的门票,此时互联网连接可能会很差)。不过还是挺不错的发现! - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接