qr 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -23
- package/decode.d.ts +2 -2
- package/decode.d.ts.map +1 -1
- package/decode.js +7 -11
- package/dom.d.ts.map +1 -1
- package/dom.js +18 -17
- package/index.d.ts +23 -2
- package/index.d.ts.map +1 -1
- package/index.js +54 -27
- package/package.json +21 -30
- package/src/decode.ts +897 -0
- package/src/dom.ts +352 -0
- package/src/index.ts +1261 -0
- package/esm/decode.d.ts +0 -62
- package/esm/decode.d.ts.map +0 -1
- package/esm/decode.js +0 -926
- package/esm/decode.js.map +0 -1
- package/esm/dom.d.ts +0 -102
- package/esm/dom.d.ts.map +0 -1
- package/esm/dom.js +0 -318
- package/esm/dom.js.map +0 -1
- package/esm/index.d.ts +0 -211
- package/esm/index.d.ts.map +0 -1
- package/esm/index.js +0 -1093
- package/esm/index.js.map +0 -1
- package/esm/package.json +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Minimal 0-dep QR code generator & reader.
|
|
|
6
6
|
- 🏞️ Encoding (generating) supports ASCII, term, gif and svg codes
|
|
7
7
|
- 📷 Decoding (reading) supports camera feed input, files and non-browser environments
|
|
8
8
|
- 🔍 Extensive tests ensure correctness: 100MB+ of vectors
|
|
9
|
-
- 🪶
|
|
9
|
+
- 🪶 14KB (gzipped) for encoding + decoding, 7KB for encoding
|
|
10
10
|
|
|
11
11
|
Check out:
|
|
12
12
|
|
|
@@ -41,9 +41,9 @@ A standalone file [qr.js](https://github.com/paulmillr/qr/releases) is also avai
|
|
|
41
41
|
## Encoding
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
|
-
import encodeQR from '
|
|
44
|
+
import encodeQR from 'qr';
|
|
45
45
|
|
|
46
|
-
// import decodeQR from '
|
|
46
|
+
// import decodeQR from 'qr/decode.js';
|
|
47
47
|
// See separate README section for decoding.
|
|
48
48
|
|
|
49
49
|
const txt = 'Hello world';
|
|
@@ -99,9 +99,9 @@ GIF reader is not included in the package (it would take a lot of space).
|
|
|
99
99
|
Decoding raw bitmap is still possible.
|
|
100
100
|
|
|
101
101
|
```js
|
|
102
|
-
import encodeQR from '
|
|
103
|
-
import decodeQR from '
|
|
104
|
-
import { Bitmap } from '
|
|
102
|
+
import encodeQR from 'qr';
|
|
103
|
+
import decodeQR from 'qr/decode.js';
|
|
104
|
+
import { Bitmap } from 'qr';
|
|
105
105
|
|
|
106
106
|
// Scale so it would be 100x100 instead of 25x25
|
|
107
107
|
const opts = { scale: 4 };
|
|
@@ -136,7 +136,7 @@ function decodeWithExternal() {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// c) draw gif/svg to browser DOM canvas
|
|
139
|
-
import { svgToPng } from '
|
|
139
|
+
import { svgToPng } from 'qr/dom.js';
|
|
140
140
|
const png = svgToPng(encodeQR('Hello world', 'svg'), 512, 512);
|
|
141
141
|
```
|
|
142
142
|
|
|
@@ -196,7 +196,7 @@ Check out `dom.ts` for browser-related camera code that would make your apps sim
|
|
|
196
196
|
## Using with Kotlin
|
|
197
197
|
|
|
198
198
|
```kotlin
|
|
199
|
-
@JsModule("
|
|
199
|
+
@JsModule("qr")
|
|
200
200
|
@JsNonModule
|
|
201
201
|
external object Qr {
|
|
202
202
|
@JsName("default")
|
|
@@ -238,23 +238,22 @@ Benchmarks measured with Apple M2 on MacOS 13 with node.js 19.
|
|
|
238
238
|
|
|
239
239
|
```
|
|
240
240
|
======== encode/ascii ========
|
|
241
|
-
encode/paulmillr
|
|
242
|
-
encode/qrcode-generator x
|
|
243
|
-
encode/nuintun x
|
|
241
|
+
encode/paulmillr x 2,995 ops/sec @ 333μs/op
|
|
242
|
+
encode/qrcode-generator x 6,029 ops/sec @ 165μs/op ± 1.39% (min: 142μs, max: 2ms)
|
|
243
|
+
encode/nuintun x 3,647 ops/sec @ 274μs/op
|
|
244
244
|
======== encode/gif ========
|
|
245
|
-
encode/paulmillr
|
|
246
|
-
encode/qrcode-generator x
|
|
247
|
-
encode/nuintun x
|
|
245
|
+
encode/paulmillr x 2,967 ops/sec @ 337μs/op
|
|
246
|
+
encode/qrcode-generator x 3,486 ops/sec @ 286μs/op
|
|
247
|
+
encode/nuintun x 3,643 ops/sec @ 274μs/op
|
|
248
248
|
======== encode: big ========
|
|
249
|
-
encode/paulmillr
|
|
250
|
-
encode/qrcode-generator x
|
|
251
|
-
encode/nuintun x
|
|
249
|
+
encode/paulmillr x 156 ops/sec @ 6ms/op
|
|
250
|
+
encode/qrcode-generator x 200 ops/sec @ 4ms/op
|
|
251
|
+
encode/nuintun x 223 ops/sec @ 4ms/op
|
|
252
252
|
======== decode ========
|
|
253
|
-
decode/paulmillr
|
|
254
|
-
decode/jsqr x
|
|
255
|
-
decode/nuintun x
|
|
256
|
-
decode/instascan x
|
|
257
|
-
======== Decoding quality ========
|
|
253
|
+
decode/paulmillr x 154 ops/sec @ 6ms/op ± 1.29% (min: 6ms, max: 18ms)
|
|
254
|
+
decode/jsqr x 52 ops/sec @ 18ms/op
|
|
255
|
+
decode/nuintun x 51 ops/sec @ 19ms/op
|
|
256
|
+
decode/instascan x 158 ops/sec @ 6ms/op ± 9.06% (min: 3ms, max: 144ms)======== Decoding quality ========
|
|
258
257
|
blurred(45): paulmillr-qr=12 (26.66%) jsqr=13 (28.88%) nuintun=13 (28.88%) instascan=11 (24.44%)
|
|
259
258
|
```
|
|
260
259
|
|
|
@@ -264,7 +263,7 @@ Copyright (c) 2023 Paul Miller (paulmillr.com)
|
|
|
264
263
|
|
|
265
264
|
Copyright (c) 2019 ZXing authors
|
|
266
265
|
|
|
267
|
-
The library
|
|
266
|
+
The library paulmillr-qr is dual-licensed under the Apache 2.0 OR MIT license.
|
|
268
267
|
You can select a license of your choice.
|
|
269
268
|
|
|
270
269
|
The library contains code inspired by [ZXing](https://github.com/zxing/zxing), which is licensed under Apache 2.0.
|
package/decode.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ limitations under the License.
|
|
|
22
22
|
|
|
23
23
|
```
|
|
24
24
|
*/
|
|
25
|
-
import type { Image, Point } from './index.
|
|
26
|
-
import { Bitmap } from './index.
|
|
25
|
+
import type { Image, Point } from './index.ts';
|
|
26
|
+
import { Bitmap } from './index.ts';
|
|
27
27
|
export type FinderPoints = [Pattern, Pattern, Point, Pattern];
|
|
28
28
|
/**
|
|
29
29
|
* Convert to grayscale. The function is the most expensive part of decoding:
|
package/decode.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["src/decode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;EAeE;AACF;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAiC,KAAK,
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["src/decode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;EAeE;AACF;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAiC,KAAK,EAAQ,KAAK,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,MAAM,EAAS,MAAM,YAAY,CAAC;AAgB3C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AA2B9D;;;GAGG;AACH,iBAAS,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAwEpC;AAGD,KAAK,OAAO,GAAG,KAAK,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA6I7D,iBAAS,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,OAAO,CAAC;CACb,CA8HA;AAoHD,iBAAS,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;CACtB,CAkDA;AAyJD,iBAAS,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAgFvC;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC,CAAC;AAsBF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,GAAE,UAAe,GAAG,MAAM,CA8BlE;AAED,eAAe,QAAQ,CAAC;AAGxB,eAAO,MAAM,MAAM,EAAE;IACnB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,MAAM,EAAE,OAAO,MAAM,CAAC;CAMvB,CAAC"}
|
package/decode.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*!
|
|
3
2
|
Copyright (c) 2023 Paul Miller (paulmillr.com)
|
|
4
3
|
The library paulmillr-qr is dual-licensed under the Apache 2.0 OR MIT license.
|
|
@@ -23,11 +22,8 @@ limitations under the License.
|
|
|
23
22
|
|
|
24
23
|
```
|
|
25
24
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
exports.decodeQR = decodeQR;
|
|
29
|
-
const index_js_1 = require("./index.js");
|
|
30
|
-
const { best, bin, drawTemplate, fillArr, info, interleave, validateVersion, zigzag } = index_js_1.utils;
|
|
25
|
+
import { Bitmap, utils } from "./index.js";
|
|
26
|
+
const { best, bin, drawTemplate, fillArr, info, interleave, validateVersion, zigzag } = utils;
|
|
31
27
|
// Constants
|
|
32
28
|
const MAX_BITS_ERROR = 3; // Up to 3 bit errors in version/format
|
|
33
29
|
const GRAYSCALE_BLOCK_SIZE = 8;
|
|
@@ -115,7 +111,7 @@ function toBitmap(img) {
|
|
|
115
111
|
blocks[bWidth * y + x] = int(average);
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
|
-
const matrix = new
|
|
114
|
+
const matrix = new Bitmap({ width: img.width, height: img.height });
|
|
119
115
|
for (let y = 0; y < bHeight; y++) {
|
|
120
116
|
const yPos = cap(y * block, 0, maxY);
|
|
121
117
|
const top = cap(y, 2, bHeight - 3);
|
|
@@ -660,7 +656,7 @@ function transform(b, size, from, to) {
|
|
|
660
656
|
];
|
|
661
657
|
const sToQ = squareToQuadrilateral(from);
|
|
662
658
|
const transform = sToQ.map((i) => i.map((_, qx) => i.reduce((acc, v, j) => acc + v * qToS[j][qx], 0)));
|
|
663
|
-
const res = new
|
|
659
|
+
const res = new Bitmap(size);
|
|
664
660
|
const points = fillArr(2 * size, 0);
|
|
665
661
|
const pointsLength = points.length;
|
|
666
662
|
for (let y = 0; y < size; y++) {
|
|
@@ -886,7 +882,7 @@ function cropToSquare(img) {
|
|
|
886
882
|
}
|
|
887
883
|
return { offset, img: { height: squareSize, width: squareSize, data: croppedData } };
|
|
888
884
|
}
|
|
889
|
-
function decodeQR(img, opts = {}) {
|
|
885
|
+
export function decodeQR(img, opts = {}) {
|
|
890
886
|
for (const field of ['height', 'width']) {
|
|
891
887
|
if (!Number.isSafeInteger(img[field]) || img[field] <= 0)
|
|
892
888
|
throw new Error(`invalid img.${field}=${img[field]} (${typeof img[field]})`);
|
|
@@ -919,9 +915,9 @@ function decodeQR(img, opts = {}) {
|
|
|
919
915
|
opts.imageOnResult(bits.toImage());
|
|
920
916
|
return res;
|
|
921
917
|
}
|
|
922
|
-
|
|
918
|
+
export default decodeQR;
|
|
923
919
|
// Unsafe API utils, exported only for tests
|
|
924
|
-
|
|
920
|
+
export const _tests = {
|
|
925
921
|
toBitmap,
|
|
926
922
|
decodeBitmap,
|
|
927
923
|
findFinder,
|
package/dom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["src/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;EAeE;AACF;;;;;;;GAOG;AAKH,eAAO,MAAM,OAAO,GAClB,KAAK,WAAW,KACf;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAMhB,CAAC;AAmBF,MAAM,MAAM,YAAY,GAAG;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,CAAC;AACF;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAGnC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAE,gBAAqB,EACpD,IAAI,GAAE,OAAO,CAAC,YAAY,CAAM;IAoBlC,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,WAAW;IAgDnB,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAmBtF,KAAK,IAAI,IAAI;CAMd;AAED,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAmB;gBACrB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB;IAKzD,OAAO,CAAC,SAAS;IAQjB;;;OAGG;IACG,WAAW,IAAI,OAAO,CAC1B;QACE,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CACJ;IAWD;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,UAAQ,GAAG,MAAM,GAAG,SAAS;IAMjE,IAAI,IAAI,IAAI;CAGb;AACD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAY/E;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAY9D;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["src/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;EAeE;AACF;;;;;;;GAOG;AAKH,eAAO,MAAM,OAAO,GAClB,KAAK,WAAW,KACf;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAMhB,CAAC;AAmBF,MAAM,MAAM,YAAY,GAAG;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,CAAC;AACF;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAGnC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAE,gBAAqB,EACpD,IAAI,GAAE,OAAO,CAAC,YAAY,CAAM;IAoBlC,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,WAAW;IAgDnB,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAmBtF,KAAK,IAAI,IAAI;CAMd;AAED,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAmB;gBACrB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB;IAKzD,OAAO,CAAC,SAAS;IAQjB;;;OAGG;IACG,WAAW,IAAI,OAAO,CAC1B;QACE,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CACJ;IAWD;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,UAAQ,GAAG,MAAM,GAAG,SAAS;IAMjE,IAAI,IAAI,IAAI;CAGb;AACD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAY/E;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAY9D;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2CxF"}
|
package/dom.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*!
|
|
3
2
|
Copyright (c) 2023 Paul Miller (paulmillr.com)
|
|
4
3
|
The library paulmillr-qr is dual-licensed under the Apache 2.0 OR MIT license.
|
|
@@ -23,19 +22,13 @@ limitations under the License.
|
|
|
23
22
|
* The code is fragile: it is easy to make subtle errors, which will break decoding.
|
|
24
23
|
* @module
|
|
25
24
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
exports.frontalCamera = frontalCamera;
|
|
29
|
-
exports.frameLoop = frameLoop;
|
|
30
|
-
exports.svgToPng = svgToPng;
|
|
31
|
-
const decode_js_1 = require("./decode.js");
|
|
32
|
-
const getSize = (elm) => {
|
|
25
|
+
import decodeQR, {} from "./decode.js";
|
|
26
|
+
export const getSize = (elm) => {
|
|
33
27
|
const css = getComputedStyle(elm);
|
|
34
28
|
const width = Math.floor(+css.width.split('px')[0]);
|
|
35
29
|
const height = Math.floor(+css.height.split('px')[0]);
|
|
36
30
|
return { width, height };
|
|
37
31
|
};
|
|
38
|
-
exports.getSize = getSize;
|
|
39
32
|
const setCanvasSize = (canvas, height, width) => {
|
|
40
33
|
// NOTE: setting canvas.width even to same size will clear & redraw it (flickering)
|
|
41
34
|
if (canvas.height !== height)
|
|
@@ -55,9 +48,14 @@ const clearCanvas = ({ canvas, context }) => {
|
|
|
55
48
|
/**
|
|
56
49
|
* Handles canvases for QR code decoding
|
|
57
50
|
*/
|
|
58
|
-
class QRCanvas {
|
|
51
|
+
export class QRCanvas {
|
|
52
|
+
opts;
|
|
53
|
+
lastDetect = 0;
|
|
54
|
+
main;
|
|
55
|
+
overlay;
|
|
56
|
+
bitmap;
|
|
57
|
+
resultQR;
|
|
59
58
|
constructor({ overlay, bitmap, resultQR } = {}, opts = {}) {
|
|
60
|
-
this.lastDetect = 0;
|
|
61
59
|
this.opts = {
|
|
62
60
|
resultBlockSize: 8,
|
|
63
61
|
overlayMainColor: 'green',
|
|
@@ -171,7 +169,7 @@ class QRCanvas {
|
|
|
171
169
|
if (this.resultQR)
|
|
172
170
|
options.imageOnResult = (img) => this.drawResultQr(img);
|
|
173
171
|
try {
|
|
174
|
-
const res = (
|
|
172
|
+
const res = decodeQR(data, options);
|
|
175
173
|
this.lastDetect = Date.now();
|
|
176
174
|
return res;
|
|
177
175
|
}
|
|
@@ -191,8 +189,9 @@ class QRCanvas {
|
|
|
191
189
|
clearCanvas(this.resultQR);
|
|
192
190
|
}
|
|
193
191
|
}
|
|
194
|
-
exports.QRCanvas = QRCanvas;
|
|
195
192
|
class QRCamera {
|
|
193
|
+
stream;
|
|
194
|
+
player;
|
|
196
195
|
constructor(stream, player) {
|
|
197
196
|
this.stream = stream;
|
|
198
197
|
this.player = player;
|
|
@@ -236,7 +235,7 @@ class QRCamera {
|
|
|
236
235
|
const { player } = this;
|
|
237
236
|
if (fullSize)
|
|
238
237
|
return canvas.drawImage(player, player.videoHeight, player.videoWidth);
|
|
239
|
-
const size =
|
|
238
|
+
const size = getSize(player);
|
|
240
239
|
return canvas.drawImage(player, size.height, size.width);
|
|
241
240
|
}
|
|
242
241
|
stop() {
|
|
@@ -254,7 +253,7 @@ class QRCamera {
|
|
|
254
253
|
* await camera.setDevice(devices[0].deviceId); // Change camera
|
|
255
254
|
* const res = camera.readFrame(canvas);
|
|
256
255
|
*/
|
|
257
|
-
async function frontalCamera(player) {
|
|
256
|
+
export async function frontalCamera(player) {
|
|
258
257
|
const stream = await navigator.mediaDevices.getUserMedia({
|
|
259
258
|
video: {
|
|
260
259
|
// Ask for screen resolution
|
|
@@ -274,7 +273,7 @@ async function frontalCamera(player) {
|
|
|
274
273
|
* const cancel = frameLoop((ns) => console.log(ns));
|
|
275
274
|
* cancel();
|
|
276
275
|
*/
|
|
277
|
-
function frameLoop(cb) {
|
|
276
|
+
export function frameLoop(cb) {
|
|
278
277
|
let handle = undefined;
|
|
279
278
|
function loop(ts) {
|
|
280
279
|
cb(ts);
|
|
@@ -288,7 +287,7 @@ function frameLoop(cb) {
|
|
|
288
287
|
handle = undefined;
|
|
289
288
|
};
|
|
290
289
|
}
|
|
291
|
-
function svgToPng(svgData, width, height) {
|
|
290
|
+
export function svgToPng(svgData, width, height) {
|
|
292
291
|
return new Promise((resolve, reject) => {
|
|
293
292
|
if (!(Number.isSafeInteger(width) &&
|
|
294
293
|
Number.isSafeInteger(height) &&
|
|
@@ -300,6 +299,8 @@ function svgToPng(svgData, width, height) {
|
|
|
300
299
|
const domparser = new DOMParser();
|
|
301
300
|
const doc = domparser.parseFromString(svgData, 'image/svg+xml');
|
|
302
301
|
const svgElement = doc.documentElement;
|
|
302
|
+
svgElement.setAttribute('width', String(width));
|
|
303
|
+
svgElement.setAttribute('height', String(height));
|
|
303
304
|
const rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
304
305
|
rect.setAttribute('width', '100%');
|
|
305
306
|
rect.setAttribute('height', '100%');
|
package/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export declare class Bitmap {
|
|
|
68
68
|
toString(): string;
|
|
69
69
|
toASCII(): string;
|
|
70
70
|
toTerm(): string;
|
|
71
|
-
toSVG(): string;
|
|
71
|
+
toSVG(optimize?: boolean): string;
|
|
72
72
|
toGIF(): Uint8Array;
|
|
73
73
|
toImage(isRGB?: boolean): Image;
|
|
74
74
|
}
|
|
@@ -105,6 +105,26 @@ export type QrOpts = {
|
|
|
105
105
|
border?: number | undefined;
|
|
106
106
|
scale?: number | undefined;
|
|
107
107
|
};
|
|
108
|
+
export type SvgQrOpts = {
|
|
109
|
+
/**
|
|
110
|
+
* Controls how cells are generated within the SVG.
|
|
111
|
+
*
|
|
112
|
+
* If `true`:
|
|
113
|
+
* - Cells are drawn using a single `path` element.
|
|
114
|
+
* - Pro: significantly reduces the size of the QR code (>70% smaller than
|
|
115
|
+
* unoptimized).
|
|
116
|
+
* - Con: less flexible with visually customizing cell shapes.
|
|
117
|
+
*
|
|
118
|
+
* If `false`:
|
|
119
|
+
* - Each cell is drawn with its own `rect` element.
|
|
120
|
+
* - Pro: allows more flexibility with visually customizing cells shapes.
|
|
121
|
+
* - Con: significantly increases the QR code size (>230% larger than
|
|
122
|
+
* optimized).
|
|
123
|
+
*
|
|
124
|
+
* @default true
|
|
125
|
+
*/
|
|
126
|
+
optimize?: boolean | undefined;
|
|
127
|
+
};
|
|
108
128
|
export type Output = 'raw' | 'ascii' | 'term' | 'gif' | 'svg';
|
|
109
129
|
/**
|
|
110
130
|
* Encodes (creates / generates) QR code.
|
|
@@ -122,7 +142,8 @@ const array = encodeQR(txt, 'raw'); // 2d array for canvas or other libs
|
|
|
122
142
|
```
|
|
123
143
|
*/
|
|
124
144
|
export declare function encodeQR(text: string, output: 'raw', opts?: QrOpts): boolean[][];
|
|
125
|
-
export declare function encodeQR(text: string, output: 'ascii' | 'term'
|
|
145
|
+
export declare function encodeQR(text: string, output: 'ascii' | 'term', opts?: QrOpts): string;
|
|
146
|
+
export declare function encodeQR(text: string, output: 'svg', opts?: QrOpts & SvgQrOpts): string;
|
|
126
147
|
export declare function encodeQR(text: string, output: 'gif', opts?: QrOpts): Uint8Array;
|
|
127
148
|
export default encodeQR;
|
|
128
149
|
export declare const utils: {
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*!
|
|
3
2
|
Copyright (c) 2023 Paul Miller (paulmillr.com)
|
|
4
3
|
The library paulmillr-qr is dual-licensed under the Apache 2.0 OR MIT license.
|
|
@@ -15,24 +14,20 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
15
14
|
See the License for the specific language governing permissions and
|
|
16
15
|
limitations under the License.
|
|
17
16
|
*/
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports._tests = exports.utils = exports.Encoding = exports.ECMode = exports.Bitmap = void 0;
|
|
20
|
-
exports.utf8ToBytes = utf8ToBytes;
|
|
21
|
-
exports.encodeQR = encodeQR;
|
|
22
17
|
/**
|
|
23
18
|
* Methods for encoding (generating) QR code patterns.
|
|
24
19
|
* Check out decode.ts for decoding (reading).
|
|
25
20
|
* @module
|
|
26
21
|
* @example
|
|
27
22
|
```js
|
|
28
|
-
import encodeQR from '
|
|
23
|
+
import encodeQR from 'qr';
|
|
29
24
|
const txt = 'Hello world';
|
|
30
25
|
const ascii = encodeQR(txt, 'ascii'); // Not all fonts are supported
|
|
31
26
|
const terminalFriendly = encodeQR(txt, 'term'); // 2x larger, all fonts are OK
|
|
32
27
|
const gifBytes = encodeQR(txt, 'gif'); // Uncompressed GIF
|
|
33
28
|
const svgElement = encodeQR(txt, 'svg'); // SVG vector image element
|
|
34
29
|
const array = encodeQR(txt, 'raw'); // 2d array for canvas or other libs
|
|
35
|
-
// import decodeQR from '
|
|
30
|
+
// import decodeQR from 'qr/decode.js';
|
|
36
31
|
```
|
|
37
32
|
*/
|
|
38
33
|
// We do not use newline escape code directly in strings because it's not parser-friendly
|
|
@@ -125,7 +120,7 @@ function alphabet(alphabet) {
|
|
|
125
120
|
},
|
|
126
121
|
};
|
|
127
122
|
}
|
|
128
|
-
class Bitmap {
|
|
123
|
+
export class Bitmap {
|
|
129
124
|
static size(size, limit) {
|
|
130
125
|
if (typeof size === 'number')
|
|
131
126
|
size = { height: size, width: size };
|
|
@@ -168,6 +163,9 @@ class Bitmap {
|
|
|
168
163
|
width = 0;
|
|
169
164
|
return new Bitmap({ height, width }, data);
|
|
170
165
|
}
|
|
166
|
+
data;
|
|
167
|
+
height;
|
|
168
|
+
width;
|
|
171
169
|
constructor(size, data) {
|
|
172
170
|
const { height, width } = Bitmap.size(size);
|
|
173
171
|
this.data = data || Array.from({ length: height }, () => fillArr(width, undefined));
|
|
@@ -307,18 +305,48 @@ class Bitmap {
|
|
|
307
305
|
.map((i) => i.map((j) => (j ? darkBG : whiteBG)).join(''))
|
|
308
306
|
.join(String.fromCharCode(chCodes.newline));
|
|
309
307
|
}
|
|
310
|
-
toSVG() {
|
|
311
|
-
let out = `<svg
|
|
312
|
-
|
|
313
|
-
|
|
308
|
+
toSVG(optimize = true) {
|
|
309
|
+
let out = `<svg viewBox="0 0 ${this.width} ${this.height}" xmlns="http://www.w3.org/2000/svg">`;
|
|
310
|
+
// Construct optimized SVG path data.
|
|
311
|
+
let pathData = '';
|
|
312
|
+
let prevPoint;
|
|
313
|
+
this.rectRead(0, Infinity, (point, val) => {
|
|
314
|
+
if (!val)
|
|
315
|
+
return;
|
|
316
|
+
const { x, y } = point;
|
|
317
|
+
if (!optimize) {
|
|
314
318
|
out += `<rect x="${x}" y="${y}" width="1" height="1" />`;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/d#path_commands
|
|
322
|
+
// Determine the shortest way to represent the initial cursor movement.
|
|
323
|
+
// M - Move cursor (without drawing) to absolute coordinate pair.
|
|
324
|
+
let m = `M${x} ${y}`;
|
|
325
|
+
// Only allow using the relative cursor move command if previous points
|
|
326
|
+
// were drawn.
|
|
327
|
+
if (prevPoint) {
|
|
328
|
+
// m - Move cursor (without drawing) to relative coordinate pair.
|
|
329
|
+
const relM = `m${x - prevPoint.x} ${y - prevPoint.y}`;
|
|
330
|
+
if (relM.length <= m.length)
|
|
331
|
+
m = relM;
|
|
332
|
+
}
|
|
333
|
+
// Determine the shortest way to represent the cell's bottom line draw.
|
|
334
|
+
// H - Draw line from cursor position to absolute x coordinate.
|
|
335
|
+
// h - Draw line from cursor position to relative x coordinate.
|
|
336
|
+
const bH = x < 10 ? `H${x}` : 'h-1';
|
|
337
|
+
// v - Draw line from cursor position to relative y coordinate.
|
|
338
|
+
// Z - Close path (draws line from cursor position to M coordinate).
|
|
339
|
+
pathData += `${m}h1v1${bH}Z`;
|
|
340
|
+
prevPoint = point;
|
|
315
341
|
});
|
|
316
|
-
|
|
342
|
+
if (optimize)
|
|
343
|
+
out += `<path d="${pathData}"/>`;
|
|
344
|
+
out += `</svg>`;
|
|
317
345
|
return out;
|
|
318
346
|
}
|
|
319
347
|
toGIF() {
|
|
320
348
|
// NOTE: Small, but inefficient implementation.
|
|
321
|
-
// Uses 1 byte per pixel
|
|
349
|
+
// Uses 1 byte per pixel.
|
|
322
350
|
const u16le = (i) => [i & 0xff, (i >>> 8) & 0xff];
|
|
323
351
|
const dims = [...u16le(this.width), ...u16le(this.height)];
|
|
324
352
|
const data = [];
|
|
@@ -355,13 +383,12 @@ class Bitmap {
|
|
|
355
383
|
return { height, width, data };
|
|
356
384
|
}
|
|
357
385
|
}
|
|
358
|
-
exports.Bitmap = Bitmap;
|
|
359
386
|
// End of utils
|
|
360
387
|
// Runtime type-checking
|
|
361
388
|
/** Error correction mode. low: 7%, medium: 15%, quartile: 25%, high: 30% */
|
|
362
|
-
|
|
389
|
+
export const ECMode = ['low', 'medium', 'quartile', 'high'];
|
|
363
390
|
/** QR Code encoding */
|
|
364
|
-
|
|
391
|
+
export const Encoding = ['numeric', 'alphanumeric', 'byte', 'kanji', 'eci'];
|
|
365
392
|
// Various constants & tables
|
|
366
393
|
// prettier-ignore
|
|
367
394
|
const BYTES = [
|
|
@@ -856,7 +883,7 @@ function detectType(str) {
|
|
|
856
883
|
/**
|
|
857
884
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
|
858
885
|
*/
|
|
859
|
-
function utf8ToBytes(str) {
|
|
886
|
+
export function utf8ToBytes(str) {
|
|
860
887
|
if (typeof str !== 'string')
|
|
861
888
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
|
862
889
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
|
@@ -1006,12 +1033,12 @@ function drawQRBest(ver, ecc, data, maskIdx) {
|
|
|
1006
1033
|
return drawQR(ver, ecc, data, maskIdx);
|
|
1007
1034
|
}
|
|
1008
1035
|
function validateECC(ec) {
|
|
1009
|
-
if (!
|
|
1010
|
-
throw new Error(`Invalid error correction mode=${ec}. Expected: ${
|
|
1036
|
+
if (!ECMode.includes(ec))
|
|
1037
|
+
throw new Error(`Invalid error correction mode=${ec}. Expected: ${ECMode}`);
|
|
1011
1038
|
}
|
|
1012
1039
|
function validateEncoding(enc) {
|
|
1013
|
-
if (!
|
|
1014
|
-
throw new Error(`Encoding: invalid mode=${enc}. Expected: ${
|
|
1040
|
+
if (!Encoding.includes(enc))
|
|
1041
|
+
throw new Error(`Encoding: invalid mode=${enc}. Expected: ${Encoding}`);
|
|
1015
1042
|
if (enc === 'kanji' || enc === 'eci')
|
|
1016
1043
|
throw new Error(`Encoding: ${enc} is not supported (yet?).`);
|
|
1017
1044
|
}
|
|
@@ -1019,7 +1046,7 @@ function validateMask(mask) {
|
|
|
1019
1046
|
if (![0, 1, 2, 3, 4, 5, 6, 7].includes(mask) || !PATTERNS[mask])
|
|
1020
1047
|
throw new Error(`Invalid mask=${mask}. Expected number [0..7]`);
|
|
1021
1048
|
}
|
|
1022
|
-
function encodeQR(text, output = 'raw', opts = {}) {
|
|
1049
|
+
export function encodeQR(text, output = 'raw', opts = {}) {
|
|
1023
1050
|
const ecc = opts.ecc !== undefined ? opts.ecc : 'medium';
|
|
1024
1051
|
validateECC(ecc);
|
|
1025
1052
|
const encoding = opts.encoding !== undefined ? opts.encoding : detectType(text);
|
|
@@ -1061,7 +1088,7 @@ function encodeQR(text, output = 'raw', opts = {}) {
|
|
|
1061
1088
|
else if (output === 'ascii')
|
|
1062
1089
|
return res.toASCII();
|
|
1063
1090
|
else if (output === 'svg')
|
|
1064
|
-
return res.toSVG();
|
|
1091
|
+
return res.toSVG(opts.optimize);
|
|
1065
1092
|
else if (output === 'gif')
|
|
1066
1093
|
return res.toGIF();
|
|
1067
1094
|
else if (output === 'term')
|
|
@@ -1069,8 +1096,8 @@ function encodeQR(text, output = 'raw', opts = {}) {
|
|
|
1069
1096
|
else
|
|
1070
1097
|
throw new Error(`Unknown output: ${output}`);
|
|
1071
1098
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1099
|
+
export default encodeQR;
|
|
1100
|
+
export const utils = {
|
|
1074
1101
|
best,
|
|
1075
1102
|
bin,
|
|
1076
1103
|
drawTemplate,
|
|
@@ -1081,7 +1108,7 @@ exports.utils = {
|
|
|
1081
1108
|
zigzag,
|
|
1082
1109
|
};
|
|
1083
1110
|
// Unsafe API utils, exported only for tests
|
|
1084
|
-
|
|
1111
|
+
export const _tests = {
|
|
1085
1112
|
Bitmap,
|
|
1086
1113
|
info,
|
|
1087
1114
|
detectType,
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Minimal 0-dep QR code generator & reader. Supports ascii, term, gif and svg formats",
|
|
5
5
|
"files": [
|
|
6
|
-
"esm",
|
|
7
6
|
"index.js",
|
|
8
7
|
"index.d.ts",
|
|
9
8
|
"index.d.ts.map",
|
|
@@ -16,21 +15,18 @@
|
|
|
16
15
|
"dom.d.ts",
|
|
17
16
|
"dom.d.ts.map",
|
|
18
17
|
"dom.ts",
|
|
18
|
+
"src",
|
|
19
19
|
"LICENSE",
|
|
20
20
|
"LICENSE-MIT"
|
|
21
21
|
],
|
|
22
|
-
"main": "index.js",
|
|
23
|
-
"module": "index.js",
|
|
24
|
-
"types": "index.d.ts",
|
|
25
22
|
"sideEffects": false,
|
|
26
23
|
"devDependencies": {
|
|
27
|
-
"@paulmillr/jsbt": "0.
|
|
28
|
-
"
|
|
29
|
-
"micro-bmark": "0.4.
|
|
30
|
-
"micro-should": "0.5.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"typescript": "5.8.2"
|
|
24
|
+
"@paulmillr/jsbt": "0.4.1",
|
|
25
|
+
"@types/node": "22.15.23",
|
|
26
|
+
"micro-bmark": "0.4.1",
|
|
27
|
+
"micro-should": "0.5.3",
|
|
28
|
+
"prettier": "3.5.3",
|
|
29
|
+
"typescript": "5.8.3"
|
|
34
30
|
},
|
|
35
31
|
"author": "Paul Miller (https://paulmillr.com)",
|
|
36
32
|
"license": "(MIT OR Apache-2.0)",
|
|
@@ -39,28 +35,23 @@
|
|
|
39
35
|
"type": "git",
|
|
40
36
|
"url": "git+https://github.com/paulmillr/qr.git"
|
|
41
37
|
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">= 20.19.0"
|
|
40
|
+
},
|
|
41
|
+
"type": "module",
|
|
42
|
+
"main": "index.js",
|
|
43
|
+
"module": "index.js",
|
|
44
|
+
"types": "index.d.ts",
|
|
42
45
|
"scripts": {
|
|
43
|
-
"build": "tsc
|
|
46
|
+
"build": "tsc",
|
|
44
47
|
"build:release": "npx jsbt esbuild test/build",
|
|
48
|
+
"bench": "cd test/benchmark && npm ci && node index.ts",
|
|
45
49
|
"lint": "prettier --check src",
|
|
46
50
|
"format": "prettier --write src",
|
|
47
|
-
"test": "node
|
|
48
|
-
"test:bun": "bun
|
|
49
|
-
"test:deno": "deno --allow-env --allow-read
|
|
50
|
-
|
|
51
|
-
"exports": {
|
|
52
|
-
".": {
|
|
53
|
-
"import": "./esm/index.js",
|
|
54
|
-
"require": "./index.js"
|
|
55
|
-
},
|
|
56
|
-
"./decode.js": {
|
|
57
|
-
"import": "./esm/decode.js",
|
|
58
|
-
"require": "./decode.js"
|
|
59
|
-
},
|
|
60
|
-
"./dom.js": {
|
|
61
|
-
"import": "./esm/dom.js",
|
|
62
|
-
"require": "./dom.js"
|
|
63
|
-
}
|
|
51
|
+
"test": "cd test; npm ci; node --experimental-strip-types --no-warnings index.ts",
|
|
52
|
+
"test:bun": "cd test; bun install; bun index.ts",
|
|
53
|
+
"test:deno": "cd test; npm install; deno --allow-env --allow-read index.ts",
|
|
54
|
+
"test:node20": "cd test; npx tsc; cd compiled/test; npm install; node index.js"
|
|
64
55
|
},
|
|
65
56
|
"keywords": [
|
|
66
57
|
"qr",
|