chillerlan / php-qrcode

A PHP QR Code generator and reader with a user-friendly API.
https://smiley.codes/qrcode/
Apache License 2.0
2.02k stars 302 forks source link

Decoding an apparently fine QRCode leads to "failed to read version" exception. #270

Closed rderimay closed 5 months ago

rderimay commented 5 months ago

Describe the bug or unexpected behaviour

A QRCode recognition fails with the error "failed to read version" even if the QRCode can be decoded with a phone for example.

Steps to reproduce the behavior

(new QRCode)->readFromFile($imagePath);

with imagePath being a good resolution jpg file.

It fails in file src/Decoder/BitMatrix.php, line 345

If you provide me with a way to send you the file privately or a way to track down the problem I would be happy to help. The QRCode contains personal information of someone else, so I cannot post the file in public here.

Environment (please complete the following information):

codemasher commented 5 months ago

Hi, first off: without the image producing that error I'm not in a position to help in any way. Second, the decoder does not work in the same way as it would on a mobile app - the mobile app scans the code continuously from different angles and positions and will return the first positive result it gets, while the decoder here only does a single pass on the fixed source image. The decoding algorithm is very similar to the mobile apps and in theory it could be implemented in a way to multi pass scan an image while transforming the source image, but that's not the focus of this library.

rderimay commented 5 months ago

Yes off course. Is there a way I could send it to you in a private way ? Also, I could crop and resize the image multiple times before sending it the lib. Would that help ? if yes, what would be the best transformations (change size ? change offset ? change rotation ?) to apply to maximise the chance to have a positive ? Thanks !

codemasher commented 5 months ago

Is there a way I could send it to you in a private way ?

My email address is in the file header of almost every file in this library.

Also, I could crop and resize the image multiple times before sending it the lib. Would that help ?

I assume you mean before decoding? There's many things that you could do, first, the grayscale and contrast options, rotation, resizing (smaller QR Codes produce better results for some reason), perspective transform (tilt along the axes).

Basically you could emulate the scanning of a mobile camera somewhat like this:

while(true){
    try{
        // read qrcode ...
        return $result;
    }
    catch(Throwable){
        // apply transforms to image, continue, break after X retries maybe
    }
}
codemasher commented 5 months ago

in theory it could be implemented in a way to multi pass scan an image while transforming the source image

I should add here that it's hard to estimate the correct directions for a perspective transform. Unlike a human, who looks at the output of the mobile camera's capturing input and who can position the QR Code in the app's view finder by tilting the camera in 3 axes, an algorithm here could only guess and try tilting the image back and forth a bit in hope to get a result.