From bd9d700e34daaf2b93d8932e60bd976ce8b35a6d Mon Sep 17 00:00:00 2001 From: Cosmo Wolfe Date: Wed, 27 Jun 2018 23:01:34 -0700 Subject: [PATCH] Support inverted QR codes (#67) --- src/BitMatrix.ts | 4 + src/index.ts | 16 ++- tests/end-to-end/152/output.json | 2 +- tests/end-to-end/issue-59-inverted/input.png | Bin 0 -> 1064 bytes .../end-to-end/issue-59-inverted/output.json | 91 ++++++++++++++++++ tests/end-to-end/issue-59/input.png | Bin 0 -> 1017 bytes tests/end-to-end/issue-59/output.json | 91 ++++++++++++++++++ tests/end-to-end/report.json | 4 +- 8 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 tests/end-to-end/issue-59-inverted/input.png create mode 100644 tests/end-to-end/issue-59-inverted/output.json create mode 100644 tests/end-to-end/issue-59/input.png create mode 100644 tests/end-to-end/issue-59/output.json diff --git a/src/BitMatrix.ts b/src/BitMatrix.ts index 2d3b86d1..5983ccb3 100644 --- a/src/BitMatrix.ts +++ b/src/BitMatrix.ts @@ -31,4 +31,8 @@ export class BitMatrix { } } } + + public getInverted() { + return new BitMatrix(this.data.map(d => d === 0 ? 1 : 0), this.width); + } } diff --git a/src/index.ts b/src/index.ts index 1158048e..e6fd7d74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,13 +23,12 @@ export interface QRCode { }; } -function jsQR(data: Uint8ClampedArray, width: number, height: number): QRCode | null { - const binarized = binarize(data, width, height); - const location = locate(binarized); +function scan(matrix: BitMatrix): QRCode | null { + const location = locate(matrix); if (!location) { return null; } - const extracted = extract(binarized, location); + const extracted = extract(matrix, location); const decoded = decode(extracted.matrix); if (!decoded) { @@ -55,5 +54,14 @@ function jsQR(data: Uint8ClampedArray, width: number, height: number): QRCode | }; } +function jsQR(data: Uint8ClampedArray, width: number, height: number): QRCode | null { + const binarized = binarize(data, width, height); + let result = scan(binarized); + if (!result) { + result = scan(binarized.getInverted()); + } + return result; +} + (jsQR as any).default = jsQR; export default jsQR; diff --git a/tests/end-to-end/152/output.json b/tests/end-to-end/152/output.json index e587c5c9..e49a19b3 100644 --- a/tests/end-to-end/152/output.json +++ b/tests/end-to-end/152/output.json @@ -245,4 +245,4 @@ "y": 307 } } -} +} \ No newline at end of file diff --git a/tests/end-to-end/issue-59-inverted/input.png b/tests/end-to-end/issue-59-inverted/input.png new file mode 100644 index 0000000000000000000000000000000000000000..b3e58b6ed90bb9c28d042512b1d6f08162dbdde8 GIT binary patch literal 1064 zcmeAS@N?(olHy`uVBq!ia0vp^dw_U72OE%d=iV}pfr0tGr;B4q#hkZyz4KnXi8vh8 zIPq`$njWLd34)i_{u5Z9l{0%&!G!~=v!A^FTetszQ^)@DdWHzk4@)@ai5#5#>HJ*z zy1j9m?b!dEx?8LlRuRPF-}S&#&_=UK-4&`v2}5v7^zVo6b1U}$SZ@2z*zURiccB>D zYcKY4`2T#DzWLB(n1)EJEp?lU3T|2|{404g*ZkQ0A9v5EwZhHaRGaZPrR2a&!=7Hg zx#jD&ysJBOyYv44?GX==?4P21{?eR`68qn><>&6qshIXW1<8$V*IfN>^2enk%q)6x zq3Y4pL)Jj|t)Ftw@bPY|kH7zmX(M}Q(_fvlozw56zj2qhJ^gv|#J?ZZ>%MP}L|CdL z8#TY?WYx9Lcf)!6{Qte%f07FxCQnb87oM-m{(5!wq}BJ%)jp3{?ELwi`joeJ|LWHu zf=jM`X=#b}yAy?VR@bgNR!qC7d)jzT(bDS(bAVx+v%mBAdhYq3 zQ`Fb|mB;XJ&t`e!a~eH%|K1;&KI`nS*~{P5{y&0nP3rFpR>=~#Y7c)oalZEPkJW59 zFWxT~Huq73#{5mYE%zkT!tQz0UVWip`zvVc#KeMQmruO=_a+M|Hk#B^e@D);4%=H* zcct_9&2Xz!>4WM>@*w~8SKqEYS^GupgLN41UhV(O^EaX-mw6UvdfvJ3|79M&FZR!? z^JlAO-B=}ky8bZ2sZRsLquhIW`W8DsUUNJ*e(P_xirdYJ%m?9#?q=PzXOr)ytE9!a z#b+M-nEvMD_N@$R!q5~TW4XodWRLjTvp06v9q(-Zft=VRqU|}1*uD2t(@o}8d`l5Ug!GiR&Z`+;&ytK5PP3K&_v-!o1VpO* zRCRxbT3I|}tNmTswzY_K0*h%JdF|=7U~a#ipJnP!Bl$l*?t1?kpZ@3%z!HGL)78&q Iol`;+0M%6oQ~&?~ literal 0 HcmV?d00001 diff --git a/tests/end-to-end/issue-59-inverted/output.json b/tests/end-to-end/issue-59-inverted/output.json new file mode 100644 index 00000000..fd5c7dfb --- /dev/null +++ b/tests/end-to-end/issue-59-inverted/output.json @@ -0,0 +1,91 @@ +{ + "binaryData": [ + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 119, + 119, + 119, + 46, + 113, + 114, + 115, + 116, + 117, + 102, + 102, + 46, + 99, + 111, + 109 + ], + "data": "http://www.qrstuff.com", + "chunks": [ + { + "type": "byte", + "bytes": [ + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 119, + 119, + 119, + 46, + 113, + 114, + 115, + 116, + 117, + 102, + 102, + 46, + 99, + 111, + 109 + ], + "text": "http://www.qrstuff.com" + } + ], + "location": { + "topRightCorner": { + "x": 159.66666666666669, + "y": 20.333333333333332 + }, + "topLeftCorner": { + "x": 26.085501858736055, + "y": 20.08550185873606 + }, + "bottomRightCorner": { + "x": 158.18365235385414, + "y": 152.18365235385411 + }, + "bottomLeftCorner": { + "x": 26.333333333333332, + "y": 153.66666666666666 + }, + "topRightFinderPattern": { + "x": 141, + "y": 39 + }, + "topLeftFinderPattern": { + "x": 45, + "y": 39 + }, + "bottomLeftFinderPattern": { + "x": 45, + "y": 135 + }, + "bottomRightAlignmentPattern": { + "x": 124.5, + "y": 118.5 + } + } +} \ No newline at end of file diff --git a/tests/end-to-end/issue-59/input.png b/tests/end-to-end/issue-59/input.png new file mode 100644 index 0000000000000000000000000000000000000000..a5c4a7a56cf255fe2269bb4753e02291f8458004 GIT binary patch literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^n}K*e2OE&w#_(R4fr0ser;B4q#hkZyFJ`^A5OKJe zHsk;Qr)Pd&aOf%0NiARd{N66}92WIWPmh28S@X}~fc@_O3_nB+Co85I9r0w`*AmWtzG;d-T8l6wBe@oOl16E zUM@FhOYx1W(zkQj-RJ(e>A%4UZr_evhCgRtZ7?vrv4*c8yo{lIzFN(r=lc(xLUv5f zU$e(9tG_G97e1Bl6W-5j**g{CJjM@){c09`S&wAs4J(FuJDN+M);+r_yGL8iZnd!e zf6*{xA3oleZ|ryH+1wrTE56>I5FYj}-R|S&`3b3TuNxXM)O|L4dFAJ+a^A%Ie{Qbd zgmCkXUv1Y`ZlAetcXZkH=;-w^*`*A3Yd>8)_d0qeJp5|T@;!LfenI3qTXiv0UZ{Qx85^_x6qTdv&{y_g;58 zR;weq9+)b&9DMLR{cqi)^7`j<^XJxnf4m+XIF8IKRNT3_PHeS0s`S+1)Z|AD5voGx5hU5uQ2&&Jj$h`1Q{LLJTE9;Qb$B)a* z4_;|{uil+1tpB6(`>pvuX8R?h#LTw3*&9E5-kU#vW_9`dIe+#)jc(f=fr#BZW(-nc z_l!5n+LhXU-u?fd9#XLMKYy2N@k0RNS-cquJ