qr 0.5.4 โ 0.6.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 +43 -36
- package/decode.d.ts +100 -13
- package/decode.d.ts.map +1 -1
- package/decode.js +623 -153
- package/decode.js.map +1 -1
- package/dom.d.ts +110 -13
- package/dom.d.ts.map +1 -1
- package/dom.js +138 -18
- package/dom.js.map +1 -1
- package/index.d.ts +175 -35
- package/index.d.ts.map +1 -1
- package/index.js +276 -83
- package/index.js.map +1 -1
- package/package.json +8 -4
- package/src/decode.ts +648 -177
- package/src/dom.ts +169 -31
- package/src/index.ts +500 -129
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Minimal 0-dependency QR code generator & reader.
|
|
4
4
|
|
|
5
5
|
- ๐ Auditable, 0-dependency
|
|
6
|
+
- ๐ [Fast](#speed): aims to be faster than all JS implementations
|
|
7
|
+
- ๐ Reliable: 100MB+ of extensive test vectors ensure correctness
|
|
6
8
|
- ๐๏ธ Encoding (generating) supports ASCII, term, gif, svg and png codes
|
|
7
9
|
- ๐ท Decoding (reading) supports camera feed input, files and non-browser environments
|
|
8
|
-
-
|
|
9
|
-
- ๐ Extensive tests ensure correctness: 100MB+ of vectors
|
|
10
|
-
- ๐ชถ 16KB (gzipped) for encoding + decoding, 9KB for encoding
|
|
10
|
+
- ๐ชถ 18KB (gzipped) for encoding + decoding, 9KB for encoding
|
|
11
11
|
|
|
12
12
|
Check out:
|
|
13
13
|
|
|
@@ -76,25 +76,30 @@ const larger = encodeQR(txt, 'gif', { scale: 4 });
|
|
|
76
76
|
// };
|
|
77
77
|
|
|
78
78
|
console.log(ascii);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Example output:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
85
|
+
โโ โโโโโ โ โโโโ โโโโโโโโ โโ โโโโโ โโ
|
|
86
|
+
โโ โ โ โโโโโ โโโโโ โโโโโโโ โ โ โโ
|
|
87
|
+
โโ โโโโโ โโ โโโโโโ โ โโ โ โโ โโโโโ โโ
|
|
88
|
+
โโโโโโโโโโ โ โ โโโ โ โโโ โ โโโโโโโโโโ
|
|
89
|
+
โโ โ โ โโโโโ โโ โ โโโโ โโ โโ โโโโโ
|
|
90
|
+
โโโโโ โโโโโโโโโโโ โโโ โโโ โ โโโโโ
|
|
91
|
+
โโโโโโโโโโโโ โ โ โโโโโ โโ โ โโโ โ โโโ
|
|
92
|
+
โโโ โโโโโโโโ โโโโโโโโโโโ โโโ โโโโ
|
|
93
|
+
โโโโ โ โโ โโโโโโโโโโโโโโโ โโ โ โโโโโ
|
|
94
|
+
โโโโโ โโโ โโโโโโโโโโ โโโโโโ โโ โโ โโโ
|
|
95
|
+
โโโโโโโ โโ โโโโโ โ โโโโโ โโโโ โ โ โโ
|
|
96
|
+
โโโโโโโโโ โ โ โโ โโ โ โ โโโ โโโโโ โโ
|
|
97
|
+
โโโโโโโโโโ โ โโโโโ โโ โโ โ โโโ โโโโโโ
|
|
98
|
+
โโ โโโโโ โ โโโโโ โโ โโโ โโโ โโโโโโ
|
|
99
|
+
โโ โ โ โโ โโโ โโ โโโโโ โโ โโ โโ
|
|
100
|
+
โโ โโโโโ โโ โโโ โโ โโ โ โโโโโโโ
|
|
101
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
102
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
98
103
|
```
|
|
99
104
|
|
|
100
105
|
## Decoding
|
|
@@ -143,21 +148,23 @@ function decodeWithExternal() {
|
|
|
143
148
|
### Decoding options
|
|
144
149
|
|
|
145
150
|
```ts
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
type Point = { x: number; y: number };
|
|
152
|
+
type Pattern = Point & { moduleSize: number; count: number };
|
|
153
|
+
type FinderPoints = [Pattern, Pattern, Point, Pattern];
|
|
154
|
+
type Image = {
|
|
148
155
|
height: number;
|
|
149
156
|
width: number;
|
|
150
157
|
data: Uint8Array | Uint8ClampedArray | number[];
|
|
151
158
|
};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
type DecodeOpts = {
|
|
160
|
+
cropToSquare?: boolean;
|
|
161
|
+
textDecoder?: (bytes: Uint8Array) => string;
|
|
162
|
+
pointsOnDetect?: (points: FinderPoints) => void;
|
|
163
|
+
imageOnBitmap?: (img: Image) => void;
|
|
164
|
+
imageOnDetect?: (img: Image) => void;
|
|
165
|
+
imageOnResult?: (img: Image) => void;
|
|
159
166
|
};
|
|
160
|
-
|
|
167
|
+
declare function decodeQR(img: Image, opts?: DecodeOpts): string;
|
|
161
168
|
```
|
|
162
169
|
|
|
163
170
|
### Decoding algorithm
|
|
@@ -248,14 +255,14 @@ qrcode-generator x 2,909 ops/sec @ 343ฮผs/op
|
|
|
248
255
|
nuintun x 3,470 ops/sec @ 288ฮผs/op
|
|
249
256
|
|
|
250
257
|
# encode of large qr
|
|
251
|
-
@paulmillr/qr x
|
|
258
|
+
@paulmillr/qr x 334 ops/sec @ 2ms/op
|
|
252
259
|
qrcode-generator x 174 ops/sec @ 5ms/op
|
|
253
260
|
nuintun x 221 ops/sec @ 4ms/op
|
|
254
261
|
|
|
255
262
|
# decode
|
|
256
|
-
@paulmillr/qr x
|
|
257
|
-
jsqr x 50 ops/sec @ 19ms/op
|
|
258
|
-
nuintun x 49 ops/sec @ 20ms/op
|
|
263
|
+
@paulmillr/qr x 662 ops/sec @ 1ms/op
|
|
264
|
+
jsqr x 50 ops/sec @ 19ms/op
|
|
265
|
+
nuintun x 49 ops/sec @ 20ms/op
|
|
259
266
|
instascan x 128 ops/sec @ 7ms/op ยฑ 31.44% (4ms..166ms)
|
|
260
267
|
```
|
|
261
268
|
|
package/decode.d.ts
CHANGED
|
@@ -17,43 +17,130 @@ limitations under the License.
|
|
|
17
17
|
/**
|
|
18
18
|
* Methods for decoding (reading) QR code patterns.
|
|
19
19
|
* @module
|
|
20
|
-
* @example
|
|
21
|
-
```js
|
|
22
|
-
|
|
23
|
-
```
|
|
24
20
|
*/
|
|
25
|
-
import type { Image, Point } from './index.ts';
|
|
21
|
+
import type { Image, Point, TArg, TRet } from './index.ts';
|
|
26
22
|
import { Bitmap } from './index.ts';
|
|
23
|
+
type Point4 = [Point, Point, Point, Point];
|
|
24
|
+
/** Finder and alignment points returned by the detector. */
|
|
27
25
|
export type FinderPoints = [Pattern, Pattern, Point, Pattern];
|
|
28
26
|
/**
|
|
29
27
|
* Convert to grayscale. The function is the most expensive part of decoding:
|
|
30
|
-
* it takes up to 90% of time.
|
|
28
|
+
* it takes up to 90% of time.
|
|
29
|
+
*
|
|
30
|
+
* Binarization pipeline:
|
|
31
|
+
* 1. Convert RGB/RGBA image to one luma byte per pixel.
|
|
32
|
+
* 2. Split the image into 8x8 blocks and collect per-block mean/min/max.
|
|
33
|
+
* 3. Build a 5x5 neighborhood mean over those block means.
|
|
34
|
+
* 4. Turn each 8x8 block into bitmap bits using a local cut derived from:
|
|
35
|
+
* - the neighborhood mean,
|
|
36
|
+
* - the current block statistics,
|
|
37
|
+
* - a cheap whole-image color-spread estimate,
|
|
38
|
+
* - and, on risky scenes, a local variance field over block means.
|
|
39
|
+
*
|
|
40
|
+
* Instead of producing "best looking" thresholding: we produce a
|
|
41
|
+
* bitmap where finder patterns survive perspective / blur / highlights while
|
|
42
|
+
* keeping false dark regions low enough for downstream finder selection.
|
|
31
43
|
*/
|
|
32
|
-
declare function toBitmap(img: Image): Bitmap
|
|
44
|
+
declare function toBitmap(img: TArg<Image>): TRet<Bitmap>;
|
|
33
45
|
type Pattern = Point & {
|
|
34
46
|
moduleSize: number;
|
|
35
47
|
count: number;
|
|
36
48
|
};
|
|
37
|
-
declare function findFinder(b: Bitmap): {
|
|
49
|
+
declare function findFinder(b: TArg<Bitmap>): {
|
|
38
50
|
bl: Pattern;
|
|
39
51
|
tl: Pattern;
|
|
40
52
|
tr: Pattern;
|
|
41
53
|
};
|
|
42
|
-
declare function
|
|
54
|
+
declare function findAlignment(b: TArg<Bitmap>, est: Pattern, allowanceFactor: number): Pattern;
|
|
55
|
+
declare function detect(b: TArg<Bitmap>): TRet<{
|
|
43
56
|
bits: Bitmap;
|
|
44
57
|
points: FinderPoints;
|
|
45
|
-
}
|
|
46
|
-
declare function
|
|
58
|
+
}>;
|
|
59
|
+
declare function transform(b: TArg<Bitmap>, size: number, from: Point4, to: Point4): TRet<Bitmap>;
|
|
60
|
+
declare function decodeBitmap(b: TArg<Bitmap>, decoder?: TArg<(bytes: Uint8Array, eci: number) => string>): string;
|
|
61
|
+
/** QR decoding hooks and image preprocessing options. */
|
|
47
62
|
export type DecodeOpts = {
|
|
63
|
+
/** Crop rectangular inputs to a centered square before decoding. */
|
|
48
64
|
cropToSquare?: boolean;
|
|
49
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Custom byte-to-text decoder used for byte segments.
|
|
67
|
+
*
|
|
68
|
+
* Receives the byte segment and, when needed, the active ECI designator.
|
|
69
|
+
* ISO/IEC 18004:2024 ยง7.4.3.4 keeps ECIs active "until the end of
|
|
70
|
+
* the encoded data or a change of ECI", so callers need the active
|
|
71
|
+
* designator to apply their own charset policy.
|
|
72
|
+
* @param bytes - Byte segment payload to decode.
|
|
73
|
+
* @param eci - Active ECI designator for the byte segment.
|
|
74
|
+
* @returns Decoded text for the byte segment.
|
|
75
|
+
*/
|
|
76
|
+
textDecoder?: TArg<(bytes: Uint8Array, eci?: number) => string>;
|
|
77
|
+
/**
|
|
78
|
+
* Callback invoked with finder/alignment points after detection succeeds.
|
|
79
|
+
*
|
|
80
|
+
* Receives finder and alignment points returned by the detector.
|
|
81
|
+
* @param points - Finder and alignment points returned by the detector.
|
|
82
|
+
*/
|
|
50
83
|
pointsOnDetect?: (points: FinderPoints) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Callback invoked with the grayscale bitmap that the detector sees.
|
|
86
|
+
*
|
|
87
|
+
* Receives the grayscale image generated during bitmap conversion.
|
|
88
|
+
* @param img - Grayscale image generated during bitmap conversion.
|
|
89
|
+
*/
|
|
51
90
|
imageOnBitmap?: (img: Image) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Callback invoked with the perspective-corrected QR image.
|
|
93
|
+
*
|
|
94
|
+
* Receives the perspective-corrected QR image.
|
|
95
|
+
* @param img - Perspective-corrected QR image.
|
|
96
|
+
*/
|
|
52
97
|
imageOnDetect?: (img: Image) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Callback invoked with the final decoded QR image.
|
|
100
|
+
*
|
|
101
|
+
* Receives the final QR image used to decode the payload.
|
|
102
|
+
* @param img - Final QR image used to decode the payload.
|
|
103
|
+
*/
|
|
53
104
|
imageOnResult?: (img: Image) => void;
|
|
54
105
|
};
|
|
55
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Decode text from a QR image.
|
|
108
|
+
* @param img - RGB or RGBA image data that contains a QR code.
|
|
109
|
+
* @param opts - Decoder hooks and image preprocessing options. See {@link DecodeOpts}.
|
|
110
|
+
* @returns Decoded QR payload as a string.
|
|
111
|
+
* @throws If the image, decoder options, or QR contents are invalid. {@link Error}
|
|
112
|
+
* @example
|
|
113
|
+
* Decode text from a QR image.
|
|
114
|
+
* ```ts
|
|
115
|
+
* import encodeQR, { Bitmap } from 'qr';
|
|
116
|
+
* import decodeQR from 'qr/decode.js';
|
|
117
|
+
* const bits = encodeQR('Hello world', 'raw', { scale: 4 });
|
|
118
|
+
* const bm = new Bitmap({ width: bits[0].length, height: bits.length }, bits);
|
|
119
|
+
* const text = decodeQR(bm.toImage());
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function decodeQR(img: TArg<Image>, opts?: TArg<DecodeOpts>): string;
|
|
123
|
+
/**
|
|
124
|
+
* Default export alias for {@link decodeQR}.
|
|
125
|
+
* @param img - RGB or RGBA image data that contains a QR code.
|
|
126
|
+
* @param opts - Decoder hooks and image preprocessing options. See {@link DecodeOpts}.
|
|
127
|
+
* @returns Decoded QR payload as a string.
|
|
128
|
+
* @throws If the image, decoder options, or QR contents are invalid. {@link Error}
|
|
129
|
+
* @example
|
|
130
|
+
* Decode a rendered QR image via the default decoder export.
|
|
131
|
+
* ```ts
|
|
132
|
+
* import encodeQR, { Bitmap } from 'qr';
|
|
133
|
+
* import decodeQR from 'qr/decode.js';
|
|
134
|
+
* const bits = encodeQR('Hello world', 'raw', { scale: 4 });
|
|
135
|
+
* const bm = new Bitmap({ width: bits[0].length, height: bits.length }, bits);
|
|
136
|
+
* decodeQR(bm.toImage());
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
56
139
|
export default decodeQR;
|
|
140
|
+
export declare const _TESTS: {
|
|
141
|
+
findAlignment: typeof findAlignment;
|
|
142
|
+
transform: typeof transform;
|
|
143
|
+
};
|
|
57
144
|
export declare const _tests: {
|
|
58
145
|
toBitmap: typeof toBitmap;
|
|
59
146
|
decodeBitmap: typeof decodeBitmap;
|
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
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["src/decode.ts"],"names":[],"mappings":"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"}
|