Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Should a scanned QR code's recreation be more true to the original? If so, how? #507

Open
Sophira opened this issue Oct 23, 2024 · 7 comments

Comments

@Sophira
Copy link

Sophira commented Oct 23, 2024

Hi there,

For a while, I've been trying to work out why the QR code recreation displayed after scanning a QR code isn't exactly the same as the one scanned. As far as I can tell, the answer comes down to two things:

  1. The mask pattern and error correction level used in the recreation of the barcode are automatically selected,
  2. The generated QR code includes ECI data to specify the encoding in use, even if the original did not (and potentially also re-encodes the input as UTF-8, but I haven't checked that).

I wouldn't be surprised if it also automatically selects other settings, such as the encoding mode (if more than one can apply), QR code version, etc.

All these things are reasonable when creating a new QR code (and, to be fair, are also reasonable if you want another person to be able to scan the QR code from your phone), but displaying a recreation at all makes it look like the QR code being shown is an exact replica of the original. Given that the people most likely to be using this app in the first place are going to be curious souls, it seems like it could make sense to try to recreate the original code as accurately as possible.

In my view, there are two very different ways this could potentially be done:

  1. Procedurally generate the QR code in the same way that the app currently does, but to use the original's settings. This would allow for "canonical" QR codes to be shown without errors, and would be ideal if re-scanning the code on-screen.
  2. Instead of generating the code ourselves, the displayed QR code could be displayed using the detected input data (quantised into modules, rather than just displaying the original image data). This would allow for preserving intentional errors (to an extent, at least, limited by the resolution of the QR code), and allow the effect of errors to be shown.

I imagine the second method is likely the easier method to code (since other factors will also come into play that might not be easily identifiable after a scan, such as the segmenting used on the input data), and probably also the method that people would find most interesting - but I also see value in the first.

I'm willing to attempt to learn the app's innards to try to add this support if possible (for QR codes, at least - though I will admit I'm no expert in the matter - very much the opposite, in fact), but I don't know if this is something people even want or if this is just something that bothers me alone. I'd be very interested if this is something people would be interested in, and if so, what people would most want to see.

@markusfisch
Copy link
Owner

Hi, and thanks for bringing this topic up! In fact it doesn't really sit right with me, too, that the recreation doesn't (mostly) match the original.

Of course, this is primarily an esthetic thing since the recreation contains exactly the same content, but I totally understand your irritation, and I am already about to use the same mask type for the recreation. There's this pending PR for ZXing-C++, which is the library this app uses to read barcodes. This was triggered by this feature request.

However, using the same mask type would still not guarantee an exact replica. I really like your idea of using the detected input data, but this isn't currently possible with the (and my) Android API of ZXing-C++, unfortunately.

@relikd
Copy link

relikd commented Oct 28, 2024

Hey there, wow, this discussion is really recent! I came here to ask for exactly that. I had an issue once with a flight ticket and a QR code that was "just" reproduced instead of being the original QR code. So I wonder whether the copy did loose some kind of validity. E.g. if the reader expects some error correction but then the copy is missing it or some. Anyhow, I was searching for an app that truely duplicates a QR code just to be safe.

I assume BinaryEye is using third party libraries for the scanning? Otherwise, couldn't we just inspect the scanning process? At some point the QR code is read dot-by-dot to determine its value. Can we intercept that point? Can we get the information of all the QR "pixels"?

@T3rm1
Copy link

T3rm1 commented Nov 30, 2024

Of course, this is primarily an esthetic thing since the recreation contains exactly the same content, but I totally understand your irritation

@markusfisch I believe this is not entirely true. I have had multiple QR codes that could be scanned without any problems but when presenting them to a scanner device at an entry control, although the device was able to scan them, they didn't accept them. Only the original QR code worked. I verified that the string value was the same, at least the printable characters.
I had the same problem with a package return label. Unfortunately I don't remember which company it was. I think it was DPD.

In case you want to investigate this, I think I might still have the QR code for the entry control. Other than that I use a backup QR code scanner for important things. It's very reliable and super fast and hasn't failed me before (unfortunately with ads and probably trackers). I hope it's ok if I mention it here so that you can compare the results of scanned QR codes. It's on Play Store with id = net.qrbot

Edit: Just tested it again with a Amazon return QR code. The text is exactly the same but the generated QR was not accepted at the postal office. I had to show the original code.
I scanned another of the Amazon QR codes, this time with the above mentioned scanner, it it was accepted by the postal office. So maybe something else is broken here.

@Sophira
Copy link
Author

Sophira commented Dec 5, 2024

I really like your idea of using the detected input data, but this isn't currently possible with the (and my) Android API of ZXing-C++, unfortunately.

I plunged into the ZXing-C++ codebase to see what I could find in this regard, and it looks like there may be hope. When compiling it, you have the option to enable an experimental API (cmake -DZXING_EXPERIMENTAL_API=ON), and when you do this, the Barcode/Result class (obtained from Reader::decode) has a symbol method you can call that returns the raw sampled bits from the detector, before decoding. So... maybe this is a thing coming soon? Fingers crossed.

[edit: Fixed link to point to correct method.]

@markusfisch
Copy link
Owner

I believe this is not entirely true.

@T3rm1 You'e right - there are certain ways to include more data in a QR Code than what is returned with an ordinary barcode reader. For example, it is possible to encode data after the terminator. This is how so-called Secure QR Codes work.

I still have to check the QR Code scanner you mentioned (thanks for that!) to see if and how I maybe can improve ZXingC++ to better deal with these QR Codes. But this is a very special area, and I'm not sure if it's really worth the time to play cat and mouse with people that like to hide something in QR Codes 😉

Still, from a user perspective, the reconstruction should be as accurate as possible, of course. And with the experimental API @Sophira mentioned (thank you!), it may soon be possible to do a perfect reconstruction without having to "understand" the QR Code.

@Sophira
Copy link
Author

Sophira commented Dec 7, 2024

As an example of this symbol method working, btw, here's what the example/ZXingReader program returns when I use its -symbol argument (only available with the experimental API) with https://github.com/ohno/github-qr/blob/main/assets/img/README.png (which I chose because of the intentional errors; also please excuse the terminal colours, I changed them temporarily simply so the QR code colours would be correct):

image

So it would definitely appear to be what we want! Hopefully it makes its way to the stable API soon.

@markusfisch
Copy link
Owner

Yes, this would definitely what we what! 👍

And because I already use my own fork of ZXingCpp, it would be quite simple to add this in Binary Eye! I will just have to allocate some time to actually do it 🙈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants