ericblade / quagga2-reader-qr

Quagga2 sample external reader for QR codes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

use a more up to date qr scanner library

ericblade opened this issue · comments

While the initial version of the code does work, the 'qrcode-reader' lib has been deprecated per it's README https://github.com/edi9999/jsqrcode

Author of that lib suggests https://github.com/cozmo/jsQR which was last updated in Feb 2019, and has according to github, 1657 other projects that depend on it.. probably not a bad choice, though there may (or may not) be others that are more recently maintained, have better something or other..

There are probably many others. Another one is https://github.com/nuintun/qrcode which was just updated a few days ago, but has only 1 github dependant, despite having had hundreds of commits

I'm trying to integrate with https://github.com/cozmo/jsQR.

But it seems inputImageWrapper.data is incompatible with data expected by jsQR. So something like this will throw an error

decodeImage(inputImageWrapper) {
const code = jsQR(
      inputImageWrapper.data,
      inputImageWrapper.size.x,
      inputImageWrapper.size.y,
      { inversionAttempts: 'attemptBoth' }
    );
...

As per their documentation, jsQR is expecting

imageData - An Uint8ClampedArray of RGBA pixel values in the form [r0, g0, b0, a0, r1, g1, b1, a1, ...]. As such the length of this array should be 4 * width * height. This data is in the same form as the ImageData interface, and it's also commonly returned by node modules for reading images.

But the returned Uint8Array size from quagga2 is about width * height. So I guess this is not an rgba encoded array.

From there I'm not sure what to do.

Do you have an idea? How could I convert quagga array to make it compatible with jsqr

Thx

I'm not yet intimately familiar with this, but per quagga2/src/common/image_wrapper.js, reading the comments on all the functions, it looks like it's storing grey-scale image data, rather than RGBA.

I haven't actually examined the inputImageWrapper.data but my suspicion is that something like

const data = inputImageWrapper.data.map(grayValue => [grayValue, grayValue, grayValue, 255])

might get you pretty close, there. I'm not sure if setting all three colors to the same value is exactly equivalent to making a 8-bit greyscale image into RGBA.

@Ethorsen just sending a ping in case you didn't see this reply originally. if you're busy, that's cool. :-)

well.. i messed with this for a bit today, and .. yeah, my suggestion doesn't work right off the bat. I don't see an obvious way from here to there, but i'm sure there's something... seems worst case might be to thread the original image data through quagga.. not sure quite yet where that might be possible though.

Aha! got it! There's a bit of code already in quagga to deal with the issue, it's just wired to go straight to canvas. My initial implementation was pretty close, but not quite there (i was giving you arrays of arrays, rather than a flat array.. and that didn't work because Uint8Array can't hold arrays, among many other reasons.. oops)

@Ethorsen should be all good to go, at least it works with the 1 test image i've added to e2e/cypress/fixtures

tests are not working out right, i'm somehow getting cypress stuck in an infinite loop but that doesn't seem to be the fault of this library.