I'm using the upng-js
module to read png files. In common sense the return value should be in RGBA form, so should be an Unit8Array
with size 4*width
*height
. However when I'm reading an image with size 111*111 it returns an Unit8Array
with size 49395. Here's my code:
const jsQR = require('jsqr');
const upng = require('upng-js');
const fs = require('fs');
const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG8AAABvCAYAAADixZ5gAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAYHSURBVHhe7d3Rlhs3DAPQ v8/usnJzIN9PPJehNLa2rDPioYCCBCSm/b2/ 9//ut/tkTg1uRtydufopu8fblr8jbmrslr8nZGYOPahzPvdrtNP9Yo2Mq3VoTi /K/qM67/ snCUFdojbKG1 axHQKAJuCkqTFyDWygvAultaUl6l69PuHh1P9pE1lf0F koN9/vLPjTzmjyh7VgjoMtusk TdyIpYM0CfdY MXkSZEbpS1KZzEXZ5x4gWS81i62NmmAWbg81SNqUwwtYsk T5/bbyju7rpUXALFixsxS/2gmSXD752xTQJGI3 R9kb5mDd5W3nM7xta9Y2CpKKwSmioRf1bTb582m7wzkbbyXtuXqC29/0kgkrESXxVWHEbudqK20RqpWVKizCQBvVJPyTblw2knNnnPqEoTtPKCdL2l8lK1VTx9tX195/4rcIttc0UR3wliRTGVOlfg1uSdCKwm9W3kzfrwaJ9Zl1YZ7OlZVuyZ1iDr3/ZvTDd5Qs/rNU3eBT7bK08Gddo76a8HAmKq4LRmqWF0r02/FeOz4nlMrgpyMAGuyQusQ8Bq8qQ1n9csUd7flXL8KXn6kp9p7muQQ1ZUO6tm2UewHe4jtikfSNVWmalN3oE2vW02eSdYd3 nQtziI5QnnV65jIslrrDBNCUKGemaUYYQzEl5slGTN3fGC ZN3tl1kqJTVY2UXbHchz0lsEjRElhmWZ EnUrN6VlWrJecUVJe2q1N3mtKxCpbedLWF2vE7kbhK210KTF mJZ0JGsk6cnvbbOCkiRe ZbULLYv9TR5XyiMFAD3v5TUJk Q/4nkiUdLyhJ7lH3EimfVLN Sa4D0jtT8rW bs2K6BARZIyDKPnKuODEW/jMmdFWQw5NHQ6FpWhPQpX7ZZxvyxO7kwClwsl7ui7OSYaWeNFWKAOie1 QJbccaISltdLFfuirIAJfBK8FEIGvlnU2Tvm0KkUKArElJkvWiEqlNlCHWnVol2WZ6yMph5JCyf5N3ItnkvdafNJM05XLlpfFdbCctenUzyf7pVaEyYshFZOY1eQcCTd6FLMWCRBmpmkfXIXlETv9sWts05aUdJ16f7imHEUBljTRK5d4mdirnpeexFOgm7xkBITtWvMy8Ju 8FMPvdqPGfRt5UtDIjuTPikWk 8t301QsNaSNLhY6dDJRXgqEPJWlFiHACRkSjmSfFHSZo3GoafKEquc125Anfi3qTLtPOnEWiKmyU cQN5LzPtQpymvyPD3KzBOti73HV4VKB7XyhLZjTYm8WXe1kRVIE4g1iW1KmpV6UlsTKxalDteMbLPJe60SUUaTdyKQWq6oVsCVICZmKA4xqidWXmo1szoxBUvqFJKk/rSB0pERN1yaNtPuEPuVzq3MhibvAuG06wXEVt6BgGBbuipU7n9CkiRAsRoCAh6dV3xLcBi6V2qbFd9P7bHJe41YKy9Isz9KeZKmJGikipTZKemxEqZkf3GOt9lmk/eFrYV/sWaE55KZ1 RtTF46AyoWUbE4aTJZszpdp3foJYElPaTMjybvGYEm76IrZjnKrCAWv23Khytr5L4oSXW1amfVkJ6XHhbSn4QqhImnU9GD15C0NonyTd4FqmknCvFN3sWLQwpKmipnqW1FQ6TqTGtIf d7aGJ522zyXiOQBhxJ4zLLKW02eRuTJ10g9zDpuLRR0kAhNijPVGL1MqfTfWLbbPIuLshh4k1noTQx2WaT90PIE9upDHCxmtEa6VZZk9Yvey5J4JI201mVHj6dW03egUBsm628E7jCb3WzAtFHkDfLUtLklq7/uET9CbbZ5Pk9snRVWGGbTd7G5EnAEctKU58EpXQ SSNOs tPsM0mL227D02baVeKjYsa5PqRKnWk2vSMQ9dJlZf2iBQqT0cV xJlp00gr04r9iwFlibvQKDJOzuhlecNESsvVZvMmMovyGk90hwrlCR1iqWXZp4UIWvkjVRAlG NAkgJrElPYrOCDD2PpWC18hyxUjON0qZ/vle CwH6/yq8q7j 7msEmryNO6TJa/I2RmDj0lt5G5P3C5einFk/dclYAAAAAElFTkSuQmCC';
const regex = /^data:. \/(. );base64,(.*)$/;
const matchObj = dataUrl.match(regex);
const ext = matchObj[1];
const data = matchObj[2];
const buf = Buffer.from(data, 'base64');
// console.log(buf);
fs.writeFileSync('test.' ext, buf);
const imgInfo = upng.decode(buf);
console.log(imgInfo);
const url = jsQR(imgInfo.data, imgInfo.width, imgInfo.height);
console.log(url);
Printed image info is below:
{
tabs: { sRGB: 0 },
frames: [],
width: 111,
height: 111,
depth: 8,
ctype: 6,
data: Uint8Array(49395) [
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255,
... 49295 more items
]
}
The image is well restored on disk by writeFileSync
function.
Error thrown by jsQR
:
/home/vector/node_modules/jsqr/dist/jsQR.js:412
throw new Error("Malformed data passed to binarizer.");
CodePudding user response:
At first, let's convert your image to RGBA8
format, then create a Uint8ClampedArray
- Input of jsQR
.
// ...
const rgba8 = upng.toRGBA8(imgInfo)[0]; // convert to RGBA8
const qrArray = new Uint8ClampedArray(rgba8); // create Uint8ClampedArray array
const code = jsQR(qrArray, imgInfo.width, imgInfo.height);
console.log(code);
The output of your QR code will look like this (on my laptop):
{
binaryData: [
104, 116, 116, 112, 58, 47, 47, 116, 120, 122, 46,
113, 113, 46, 99, 111, 109, 47, 112, 63, 107, 61,
88, 87, 114, 102, 49, 105, 116, 45, 72, 105, 108,
113, 101, 119, 121, 52, 71, 85, 51, 118, 119, 84,
90, 77, 51, 70, 108, 57, 53, 49, 116, 116, 38,
102, 61, 50, 49, 48, 48, 48, 53, 48, 49
],
data: 'http://txz.qq.com/p?k=XWrf1it-Hilqewy4GU3vwTZM3Fl951tt&f=21000501',
chunks: [
{
type: 'byte',
bytes: [Array],
text: 'http://txz.qq.com/p?k=XWrf1it-Hilqewy4GU3vwTZM3Fl951tt&f='
},
{ type: 'numeric', text: '21000501' }
],
version: 4,
location: {
topRightCorner: { x: 104.99999999999999, y: 6.0000000000000036 },
topLeftCorner: { x: 6.000000000000003, y: 6.000000000000003 },
bottomRightCorner: { x: 104.99999999999997, y: 104.99999999999997 },
bottomLeftCorner: { x: 6.0000000000000036, y: 104.99999999999999 },
topRightFinderPattern: { x: 94.5, y: 16.5 },
topLeftFinderPattern: { x: 16.5, y: 16.5 },
bottomLeftFinderPattern: { x: 16.5, y: 94.5 },
bottomRightAlignmentPattern: { x: 85.5, y: 85.5 }
}
}