weapp-qrcode.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. const _my = require("../../__antmove/api/index.js")(my);
  2. const wx = _my;
  3. // Core code comes from https://github.com/davidshimjs/qrcodejs
  4. var QRCode;
  5. (function() {
  6. /**
  7. * Get the type by string length
  8. *
  9. * @private
  10. * @param {String} sText
  11. * @param {Number} nCorrectLevel
  12. * @return {Number} type
  13. */
  14. function _getTypeNumber(sText, nCorrectLevel) {
  15. var nType = 1;
  16. var length = _getUTF8Length(sText);
  17. for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
  18. var nLimit = 0;
  19. switch (nCorrectLevel) {
  20. case QRErrorCorrectLevel.L:
  21. nLimit = QRCodeLimitLength[i][0];
  22. break;
  23. case QRErrorCorrectLevel.M:
  24. nLimit = QRCodeLimitLength[i][1];
  25. break;
  26. case QRErrorCorrectLevel.Q:
  27. nLimit = QRCodeLimitLength[i][2];
  28. break;
  29. case QRErrorCorrectLevel.H:
  30. nLimit = QRCodeLimitLength[i][3];
  31. break;
  32. }
  33. if (length <= nLimit) {
  34. break;
  35. } else {
  36. nType++;
  37. }
  38. }
  39. if (nType > QRCodeLimitLength.length) {
  40. throw new Error("Too long data");
  41. }
  42. return nType;
  43. }
  44. function _getUTF8Length(sText) {
  45. var replacedText = encodeURI(sText)
  46. .toString()
  47. .replace(/\%[0-9a-fA-F]{2}/g, "a");
  48. return replacedText.length + (replacedText.length != sText ? 3 : 0);
  49. }
  50. function QR8bitByte(data) {
  51. this.mode = QRMode.MODE_8BIT_BYTE;
  52. this.data = data;
  53. this.parsedData = [];
  54. // Added to support UTF-8 Characters
  55. for (var i = 0, l = this.data.length; i < l; i++) {
  56. var byteArray = [];
  57. var code = this.data.charCodeAt(i);
  58. if (code > 0x10000) {
  59. byteArray[0] = 0xf0 | ((code & 0x1c0000) >>> 18);
  60. byteArray[1] = 0x80 | ((code & 0x3f000) >>> 12);
  61. byteArray[2] = 0x80 | ((code & 0xfc0) >>> 6);
  62. byteArray[3] = 0x80 | (code & 0x3f);
  63. } else if (code > 0x800) {
  64. byteArray[0] = 0xe0 | ((code & 0xf000) >>> 12);
  65. byteArray[1] = 0x80 | ((code & 0xfc0) >>> 6);
  66. byteArray[2] = 0x80 | (code & 0x3f);
  67. } else if (code > 0x80) {
  68. byteArray[0] = 0xc0 | ((code & 0x7c0) >>> 6);
  69. byteArray[1] = 0x80 | (code & 0x3f);
  70. } else {
  71. byteArray[0] = code;
  72. }
  73. this.parsedData.push(byteArray);
  74. }
  75. this.parsedData = Array.prototype.concat.apply([], this.parsedData);
  76. if (this.parsedData.length != this.data.length) {
  77. this.parsedData.unshift(191);
  78. this.parsedData.unshift(187);
  79. this.parsedData.unshift(239);
  80. }
  81. }
  82. QR8bitByte.prototype = {
  83. getLength: function(buffer) {
  84. return this.parsedData.length;
  85. },
  86. write: function(buffer) {
  87. for (var i = 0, l = this.parsedData.length; i < l; i++) {
  88. buffer.put(this.parsedData[i], 8);
  89. }
  90. }
  91. };
  92. // QRCodeModel
  93. function QRCodeModel(typeNumber, errorCorrectLevel) {
  94. this.typeNumber = typeNumber;
  95. this.errorCorrectLevel = errorCorrectLevel;
  96. this.modules = null;
  97. this.moduleCount = 0;
  98. this.dataCache = null;
  99. this.dataList = [];
  100. }
  101. QRCodeModel.prototype = {
  102. addData: function(data) {
  103. var newData = new QR8bitByte(data);
  104. this.dataList.push(newData);
  105. this.dataCache = null;
  106. },
  107. isDark: function(row, col) {
  108. if (
  109. row < 0 ||
  110. this.moduleCount <= row ||
  111. col < 0 ||
  112. this.moduleCount <= col
  113. ) {
  114. throw new Error(row + "," + col);
  115. }
  116. return this.modules[row][col];
  117. },
  118. getModuleCount: function() {
  119. return this.moduleCount;
  120. },
  121. make: function() {
  122. this.makeImpl(false, this.getBestMaskPattern());
  123. },
  124. makeImpl: function(test, maskPattern) {
  125. this.moduleCount = this.typeNumber * 4 + 17;
  126. this.modules = new Array(this.moduleCount);
  127. for (var row = 0; row < this.moduleCount; row++) {
  128. this.modules[row] = new Array(this.moduleCount);
  129. for (var col = 0; col < this.moduleCount; col++) {
  130. this.modules[row][col] = null;
  131. }
  132. }
  133. this.setupPositionProbePattern(0, 0);
  134. this.setupPositionProbePattern(this.moduleCount - 7, 0);
  135. this.setupPositionProbePattern(0, this.moduleCount - 7);
  136. this.setupPositionAdjustPattern();
  137. this.setupTimingPattern();
  138. this.setupTypeInfo(test, maskPattern);
  139. if (this.typeNumber >= 7) {
  140. this.setupTypeNumber(test);
  141. }
  142. if (this.dataCache == null) {
  143. this.dataCache = QRCodeModel.createData(
  144. this.typeNumber,
  145. this.errorCorrectLevel,
  146. this.dataList
  147. );
  148. }
  149. this.mapData(this.dataCache, maskPattern);
  150. },
  151. setupPositionProbePattern: function(row, col) {
  152. for (var r = -1; r <= 7; r++) {
  153. if (row + r <= -1 || this.moduleCount <= row + r) continue;
  154. for (var c = -1; c <= 7; c++) {
  155. if (col + c <= -1 || this.moduleCount <= col + c) continue;
  156. if (
  157. (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
  158. (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
  159. (2 <= r && r <= 4 && 2 <= c && c <= 4)
  160. ) {
  161. this.modules[row + r][col + c] = true;
  162. } else {
  163. this.modules[row + r][col + c] = false;
  164. }
  165. }
  166. }
  167. },
  168. getBestMaskPattern: function() {
  169. var minLostPoint = 0;
  170. var pattern = 0;
  171. for (var i = 0; i < 8; i++) {
  172. this.makeImpl(true, i);
  173. var lostPoint = QRUtil.getLostPoint(this);
  174. if (i == 0 || minLostPoint > lostPoint) {
  175. minLostPoint = lostPoint;
  176. pattern = i;
  177. }
  178. }
  179. return pattern;
  180. },
  181. createMovieClip: function(target_mc, instance_name, depth) {
  182. var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
  183. var cs = 1;
  184. this.make();
  185. for (var row = 0; row < this.modules.length; row++) {
  186. var y = row * cs;
  187. for (var col = 0; col < this.modules[row].length; col++) {
  188. var x = col * cs;
  189. var dark = this.modules[row][col];
  190. if (dark) {
  191. qr_mc.beginFill(0, 100);
  192. qr_mc.moveTo(x, y);
  193. qr_mc.lineTo(x + cs, y);
  194. qr_mc.lineTo(x + cs, y + cs);
  195. qr_mc.lineTo(x, y + cs);
  196. qr_mc.endFill();
  197. }
  198. }
  199. }
  200. return qr_mc;
  201. },
  202. setupTimingPattern: function() {
  203. for (var r = 8; r < this.moduleCount - 8; r++) {
  204. if (this.modules[r][6] != null) {
  205. continue;
  206. }
  207. this.modules[r][6] = r % 2 == 0;
  208. }
  209. for (var c = 8; c < this.moduleCount - 8; c++) {
  210. if (this.modules[6][c] != null) {
  211. continue;
  212. }
  213. this.modules[6][c] = c % 2 == 0;
  214. }
  215. },
  216. setupPositionAdjustPattern: function() {
  217. var pos = QRUtil.getPatternPosition(this.typeNumber);
  218. for (var i = 0; i < pos.length; i++) {
  219. for (var j = 0; j < pos.length; j++) {
  220. var row = pos[i];
  221. var col = pos[j];
  222. if (this.modules[row][col] != null) {
  223. continue;
  224. }
  225. for (var r = -2; r <= 2; r++) {
  226. for (var c = -2; c <= 2; c++) {
  227. if (
  228. r == -2 ||
  229. r == 2 ||
  230. c == -2 ||
  231. c == 2 ||
  232. (r == 0 && c == 0)
  233. ) {
  234. this.modules[row + r][col + c] = true;
  235. } else {
  236. this.modules[row + r][col + c] = false;
  237. }
  238. }
  239. }
  240. }
  241. }
  242. },
  243. setupTypeNumber: function(test) {
  244. var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
  245. for (var i = 0; i < 18; i++) {
  246. var mod = !test && ((bits >> i) & 1) == 1;
  247. this.modules[Math.floor(i / 3)][
  248. (i % 3) + this.moduleCount - 8 - 3
  249. ] = mod;
  250. }
  251. for (var i = 0; i < 18; i++) {
  252. var mod = !test && ((bits >> i) & 1) == 1;
  253. this.modules[(i % 3) + this.moduleCount - 8 - 3][
  254. Math.floor(i / 3)
  255. ] = mod;
  256. }
  257. },
  258. setupTypeInfo: function(test, maskPattern) {
  259. var data = (this.errorCorrectLevel << 3) | maskPattern;
  260. var bits = QRUtil.getBCHTypeInfo(data);
  261. for (var i = 0; i < 15; i++) {
  262. var mod = !test && ((bits >> i) & 1) == 1;
  263. if (i < 6) {
  264. this.modules[i][8] = mod;
  265. } else if (i < 8) {
  266. this.modules[i + 1][8] = mod;
  267. } else {
  268. this.modules[this.moduleCount - 15 + i][8] = mod;
  269. }
  270. }
  271. for (var i = 0; i < 15; i++) {
  272. var mod = !test && ((bits >> i) & 1) == 1;
  273. if (i < 8) {
  274. this.modules[8][this.moduleCount - i - 1] = mod;
  275. } else if (i < 9) {
  276. this.modules[8][15 - i - 1 + 1] = mod;
  277. } else {
  278. this.modules[8][15 - i - 1] = mod;
  279. }
  280. }
  281. this.modules[this.moduleCount - 8][8] = !test;
  282. },
  283. mapData: function(data, maskPattern) {
  284. var inc = -1;
  285. var row = this.moduleCount - 1;
  286. var bitIndex = 7;
  287. var byteIndex = 0;
  288. for (var col = this.moduleCount - 1; col > 0; col -= 2) {
  289. if (col == 6) col--;
  290. while (true) {
  291. for (var c = 0; c < 2; c++) {
  292. if (this.modules[row][col - c] == null) {
  293. var dark = false;
  294. if (byteIndex < data.length) {
  295. dark =
  296. ((data[byteIndex] >>> bitIndex) & 1) == 1;
  297. }
  298. var mask = QRUtil.getMask(
  299. maskPattern,
  300. row,
  301. col - c
  302. );
  303. if (mask) {
  304. dark = !dark;
  305. }
  306. this.modules[row][col - c] = dark;
  307. bitIndex--;
  308. if (bitIndex == -1) {
  309. byteIndex++;
  310. bitIndex = 7;
  311. }
  312. }
  313. }
  314. row += inc;
  315. if (row < 0 || this.moduleCount <= row) {
  316. row -= inc;
  317. inc = -inc;
  318. break;
  319. }
  320. }
  321. }
  322. }
  323. };
  324. QRCodeModel.PAD0 = 0xec;
  325. QRCodeModel.PAD1 = 0x11;
  326. QRCodeModel.createData = function(typeNumber, errorCorrectLevel, dataList) {
  327. var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
  328. var buffer = new QRBitBuffer();
  329. for (var i = 0; i < dataList.length; i++) {
  330. var data = dataList[i];
  331. buffer.put(data.mode, 4);
  332. buffer.put(
  333. data.getLength(),
  334. QRUtil.getLengthInBits(data.mode, typeNumber)
  335. );
  336. data.write(buffer);
  337. }
  338. var totalDataCount = 0;
  339. for (var i = 0; i < rsBlocks.length; i++) {
  340. totalDataCount += rsBlocks[i].dataCount;
  341. }
  342. if (buffer.getLengthInBits() > totalDataCount * 8) {
  343. throw new Error(
  344. "code length overflow. (" +
  345. buffer.getLengthInBits() +
  346. ">" +
  347. totalDataCount * 8 +
  348. ")"
  349. );
  350. }
  351. if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
  352. buffer.put(0, 4);
  353. }
  354. while (buffer.getLengthInBits() % 8 != 0) {
  355. buffer.putBit(false);
  356. }
  357. while (true) {
  358. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  359. break;
  360. }
  361. buffer.put(QRCodeModel.PAD0, 8);
  362. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  363. break;
  364. }
  365. buffer.put(QRCodeModel.PAD1, 8);
  366. }
  367. return QRCodeModel.createBytes(buffer, rsBlocks);
  368. };
  369. QRCodeModel.createBytes = function(buffer, rsBlocks) {
  370. var offset = 0;
  371. var maxDcCount = 0;
  372. var maxEcCount = 0;
  373. var dcdata = new Array(rsBlocks.length);
  374. var ecdata = new Array(rsBlocks.length);
  375. for (var r = 0; r < rsBlocks.length; r++) {
  376. var dcCount = rsBlocks[r].dataCount;
  377. var ecCount = rsBlocks[r].totalCount - dcCount;
  378. maxDcCount = Math.max(maxDcCount, dcCount);
  379. maxEcCount = Math.max(maxEcCount, ecCount);
  380. dcdata[r] = new Array(dcCount);
  381. for (var i = 0; i < dcdata[r].length; i++) {
  382. dcdata[r][i] = 0xff & buffer.buffer[i + offset];
  383. }
  384. offset += dcCount;
  385. var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
  386. var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
  387. var modPoly = rawPoly.mod(rsPoly);
  388. ecdata[r] = new Array(rsPoly.getLength() - 1);
  389. for (var i = 0; i < ecdata[r].length; i++) {
  390. var modIndex = i + modPoly.getLength() - ecdata[r].length;
  391. ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
  392. }
  393. }
  394. var totalCodeCount = 0;
  395. for (var i = 0; i < rsBlocks.length; i++) {
  396. totalCodeCount += rsBlocks[i].totalCount;
  397. }
  398. var data = new Array(totalCodeCount);
  399. var index = 0;
  400. for (var i = 0; i < maxDcCount; i++) {
  401. for (var r = 0; r < rsBlocks.length; r++) {
  402. if (i < dcdata[r].length) {
  403. data[index++] = dcdata[r][i];
  404. }
  405. }
  406. }
  407. for (var i = 0; i < maxEcCount; i++) {
  408. for (var r = 0; r < rsBlocks.length; r++) {
  409. if (i < ecdata[r].length) {
  410. data[index++] = ecdata[r][i];
  411. }
  412. }
  413. }
  414. return data;
  415. };
  416. var QRMode = {
  417. MODE_NUMBER: 1 << 0,
  418. MODE_ALPHA_NUM: 1 << 1,
  419. MODE_8BIT_BYTE: 1 << 2,
  420. MODE_KANJI: 1 << 3
  421. };
  422. var QRErrorCorrectLevel = {
  423. L: 1,
  424. M: 0,
  425. Q: 3,
  426. H: 2
  427. };
  428. var QRMaskPattern = {
  429. PATTERN000: 0,
  430. PATTERN001: 1,
  431. PATTERN010: 2,
  432. PATTERN011: 3,
  433. PATTERN100: 4,
  434. PATTERN101: 5,
  435. PATTERN110: 6,
  436. PATTERN111: 7
  437. };
  438. var QRUtil = {
  439. PATTERN_POSITION_TABLE: [
  440. [],
  441. [6, 18],
  442. [6, 22],
  443. [6, 26],
  444. [6, 30],
  445. [6, 34],
  446. [6, 22, 38],
  447. [6, 24, 42],
  448. [6, 26, 46],
  449. [6, 28, 50],
  450. [6, 30, 54],
  451. [6, 32, 58],
  452. [6, 34, 62],
  453. [6, 26, 46, 66],
  454. [6, 26, 48, 70],
  455. [6, 26, 50, 74],
  456. [6, 30, 54, 78],
  457. [6, 30, 56, 82],
  458. [6, 30, 58, 86],
  459. [6, 34, 62, 90],
  460. [6, 28, 50, 72, 94],
  461. [6, 26, 50, 74, 98],
  462. [6, 30, 54, 78, 102],
  463. [6, 28, 54, 80, 106],
  464. [6, 32, 58, 84, 110],
  465. [6, 30, 58, 86, 114],
  466. [6, 34, 62, 90, 118],
  467. [6, 26, 50, 74, 98, 122],
  468. [6, 30, 54, 78, 102, 126],
  469. [6, 26, 52, 78, 104, 130],
  470. [6, 30, 56, 82, 108, 134],
  471. [6, 34, 60, 86, 112, 138],
  472. [6, 30, 58, 86, 114, 142],
  473. [6, 34, 62, 90, 118, 146],
  474. [6, 30, 54, 78, 102, 126, 150],
  475. [6, 24, 50, 76, 102, 128, 154],
  476. [6, 28, 54, 80, 106, 132, 158],
  477. [6, 32, 58, 84, 110, 136, 162],
  478. [6, 26, 54, 82, 110, 138, 166],
  479. [6, 30, 58, 86, 114, 142, 170]
  480. ],
  481. G15:
  482. (1 << 10) |
  483. (1 << 8) |
  484. (1 << 5) |
  485. (1 << 4) |
  486. (1 << 2) |
  487. (1 << 1) |
  488. (1 << 0),
  489. G18:
  490. (1 << 12) |
  491. (1 << 11) |
  492. (1 << 10) |
  493. (1 << 9) |
  494. (1 << 8) |
  495. (1 << 5) |
  496. (1 << 2) |
  497. (1 << 0),
  498. G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
  499. getBCHTypeInfo: function(data) {
  500. var d = data << 10;
  501. while (
  502. QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >=
  503. 0
  504. ) {
  505. d ^=
  506. QRUtil.G15 <<
  507. (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15));
  508. }
  509. return ((data << 10) | d) ^ QRUtil.G15_MASK;
  510. },
  511. getBCHTypeNumber: function(data) {
  512. var d = data << 12;
  513. while (
  514. QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >=
  515. 0
  516. ) {
  517. d ^=
  518. QRUtil.G18 <<
  519. (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18));
  520. }
  521. return (data << 12) | d;
  522. },
  523. getBCHDigit: function(data) {
  524. var digit = 0;
  525. while (data != 0) {
  526. digit++;
  527. data >>>= 1;
  528. }
  529. return digit;
  530. },
  531. getPatternPosition: function(typeNumber) {
  532. return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
  533. },
  534. getMask: function(maskPattern, i, j) {
  535. switch (maskPattern) {
  536. case QRMaskPattern.PATTERN000:
  537. return (i + j) % 2 == 0;
  538. case QRMaskPattern.PATTERN001:
  539. return i % 2 == 0;
  540. case QRMaskPattern.PATTERN010:
  541. return j % 3 == 0;
  542. case QRMaskPattern.PATTERN011:
  543. return (i + j) % 3 == 0;
  544. case QRMaskPattern.PATTERN100:
  545. return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
  546. case QRMaskPattern.PATTERN101:
  547. return ((i * j) % 2) + ((i * j) % 3) == 0;
  548. case QRMaskPattern.PATTERN110:
  549. return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0;
  550. case QRMaskPattern.PATTERN111:
  551. return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0;
  552. default:
  553. throw new Error("bad maskPattern:" + maskPattern);
  554. }
  555. },
  556. getErrorCorrectPolynomial: function(errorCorrectLength) {
  557. var a = new QRPolynomial([1], 0);
  558. for (var i = 0; i < errorCorrectLength; i++) {
  559. a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
  560. }
  561. return a;
  562. },
  563. getLengthInBits: function(mode, type) {
  564. if (1 <= type && type < 10) {
  565. switch (mode) {
  566. case QRMode.MODE_NUMBER:
  567. return 10;
  568. case QRMode.MODE_ALPHA_NUM:
  569. return 9;
  570. case QRMode.MODE_8BIT_BYTE:
  571. return 8;
  572. case QRMode.MODE_KANJI:
  573. return 8;
  574. default:
  575. throw new Error("mode:" + mode);
  576. }
  577. } else if (type < 27) {
  578. switch (mode) {
  579. case QRMode.MODE_NUMBER:
  580. return 12;
  581. case QRMode.MODE_ALPHA_NUM:
  582. return 11;
  583. case QRMode.MODE_8BIT_BYTE:
  584. return 16;
  585. case QRMode.MODE_KANJI:
  586. return 10;
  587. default:
  588. throw new Error("mode:" + mode);
  589. }
  590. } else if (type < 41) {
  591. switch (mode) {
  592. case QRMode.MODE_NUMBER:
  593. return 14;
  594. case QRMode.MODE_ALPHA_NUM:
  595. return 13;
  596. case QRMode.MODE_8BIT_BYTE:
  597. return 16;
  598. case QRMode.MODE_KANJI:
  599. return 12;
  600. default:
  601. throw new Error("mode:" + mode);
  602. }
  603. } else {
  604. throw new Error("type:" + type);
  605. }
  606. },
  607. getLostPoint: function(qrCode) {
  608. var moduleCount = qrCode.getModuleCount();
  609. var lostPoint = 0;
  610. for (var row = 0; row < moduleCount; row++) {
  611. for (var col = 0; col < moduleCount; col++) {
  612. var sameCount = 0;
  613. var dark = qrCode.isDark(row, col);
  614. for (var r = -1; r <= 1; r++) {
  615. if (row + r < 0 || moduleCount <= row + r) {
  616. continue;
  617. }
  618. for (var c = -1; c <= 1; c++) {
  619. if (col + c < 0 || moduleCount <= col + c) {
  620. continue;
  621. }
  622. if (r == 0 && c == 0) {
  623. continue;
  624. }
  625. if (dark == qrCode.isDark(row + r, col + c)) {
  626. sameCount++;
  627. }
  628. }
  629. }
  630. if (sameCount > 5) {
  631. lostPoint += 3 + sameCount - 5;
  632. }
  633. }
  634. }
  635. for (var row = 0; row < moduleCount - 1; row++) {
  636. for (var col = 0; col < moduleCount - 1; col++) {
  637. var count = 0;
  638. if (qrCode.isDark(row, col)) count++;
  639. if (qrCode.isDark(row + 1, col)) count++;
  640. if (qrCode.isDark(row, col + 1)) count++;
  641. if (qrCode.isDark(row + 1, col + 1)) count++;
  642. if (count == 0 || count == 4) {
  643. lostPoint += 3;
  644. }
  645. }
  646. }
  647. for (var row = 0; row < moduleCount; row++) {
  648. for (var col = 0; col < moduleCount - 6; col++) {
  649. if (
  650. qrCode.isDark(row, col) &&
  651. !qrCode.isDark(row, col + 1) &&
  652. qrCode.isDark(row, col + 2) &&
  653. qrCode.isDark(row, col + 3) &&
  654. qrCode.isDark(row, col + 4) &&
  655. !qrCode.isDark(row, col + 5) &&
  656. qrCode.isDark(row, col + 6)
  657. ) {
  658. lostPoint += 40;
  659. }
  660. }
  661. }
  662. for (var col = 0; col < moduleCount; col++) {
  663. for (var row = 0; row < moduleCount - 6; row++) {
  664. if (
  665. qrCode.isDark(row, col) &&
  666. !qrCode.isDark(row + 1, col) &&
  667. qrCode.isDark(row + 2, col) &&
  668. qrCode.isDark(row + 3, col) &&
  669. qrCode.isDark(row + 4, col) &&
  670. !qrCode.isDark(row + 5, col) &&
  671. qrCode.isDark(row + 6, col)
  672. ) {
  673. lostPoint += 40;
  674. }
  675. }
  676. }
  677. var darkCount = 0;
  678. for (var col = 0; col < moduleCount; col++) {
  679. for (var row = 0; row < moduleCount; row++) {
  680. if (qrCode.isDark(row, col)) {
  681. darkCount++;
  682. }
  683. }
  684. }
  685. var ratio =
  686. Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) /
  687. 5;
  688. lostPoint += ratio * 10;
  689. return lostPoint;
  690. }
  691. };
  692. var QRMath = {
  693. glog: function(n) {
  694. if (n < 1) {
  695. throw new Error("glog(" + n + ")");
  696. }
  697. return QRMath.LOG_TABLE[n];
  698. },
  699. gexp: function(n) {
  700. while (n < 0) {
  701. n += 255;
  702. }
  703. while (n >= 256) {
  704. n -= 255;
  705. }
  706. return QRMath.EXP_TABLE[n];
  707. },
  708. EXP_TABLE: new Array(256),
  709. LOG_TABLE: new Array(256)
  710. };
  711. for (var i = 0; i < 8; i++) {
  712. QRMath.EXP_TABLE[i] = 1 << i;
  713. }
  714. for (var i = 8; i < 256; i++) {
  715. QRMath.EXP_TABLE[i] =
  716. QRMath.EXP_TABLE[i - 4] ^
  717. QRMath.EXP_TABLE[i - 5] ^
  718. QRMath.EXP_TABLE[i - 6] ^
  719. QRMath.EXP_TABLE[i - 8];
  720. }
  721. for (var i = 0; i < 255; i++) {
  722. QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
  723. }
  724. function QRPolynomial(num, shift) {
  725. if (num.length == undefined) {
  726. throw new Error(num.length + "/" + shift);
  727. }
  728. var offset = 0;
  729. while (offset < num.length && num[offset] == 0) {
  730. offset++;
  731. }
  732. this.num = new Array(num.length - offset + shift);
  733. for (var i = 0; i < num.length - offset; i++) {
  734. this.num[i] = num[i + offset];
  735. }
  736. }
  737. QRPolynomial.prototype = {
  738. get: function(index) {
  739. return this.num[index];
  740. },
  741. getLength: function() {
  742. return this.num.length;
  743. },
  744. multiply: function(e) {
  745. var num = new Array(this.getLength() + e.getLength() - 1);
  746. for (var i = 0; i < this.getLength(); i++) {
  747. for (var j = 0; j < e.getLength(); j++) {
  748. num[i + j] ^= QRMath.gexp(
  749. QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))
  750. );
  751. }
  752. }
  753. return new QRPolynomial(num, 0);
  754. },
  755. mod: function(e) {
  756. if (this.getLength() - e.getLength() < 0) {
  757. return this;
  758. }
  759. var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
  760. var num = new Array(this.getLength());
  761. for (var i = 0; i < this.getLength(); i++) {
  762. num[i] = this.get(i);
  763. }
  764. for (var i = 0; i < e.getLength(); i++) {
  765. num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
  766. }
  767. return new QRPolynomial(num, 0).mod(e);
  768. }
  769. };
  770. function QRRSBlock(totalCount, dataCount) {
  771. this.totalCount = totalCount;
  772. this.dataCount = dataCount;
  773. }
  774. QRRSBlock.RS_BLOCK_TABLE = [
  775. [1, 26, 19],
  776. [1, 26, 16],
  777. [1, 26, 13],
  778. [1, 26, 9],
  779. [1, 44, 34],
  780. [1, 44, 28],
  781. [1, 44, 22],
  782. [1, 44, 16],
  783. [1, 70, 55],
  784. [1, 70, 44],
  785. [2, 35, 17],
  786. [2, 35, 13],
  787. [1, 100, 80],
  788. [2, 50, 32],
  789. [2, 50, 24],
  790. [4, 25, 9],
  791. [1, 134, 108],
  792. [2, 67, 43],
  793. [2, 33, 15, 2, 34, 16],
  794. [2, 33, 11, 2, 34, 12],
  795. [2, 86, 68],
  796. [4, 43, 27],
  797. [4, 43, 19],
  798. [4, 43, 15],
  799. [2, 98, 78],
  800. [4, 49, 31],
  801. [2, 32, 14, 4, 33, 15],
  802. [4, 39, 13, 1, 40, 14],
  803. [2, 121, 97],
  804. [2, 60, 38, 2, 61, 39],
  805. [4, 40, 18, 2, 41, 19],
  806. [4, 40, 14, 2, 41, 15],
  807. [2, 146, 116],
  808. [3, 58, 36, 2, 59, 37],
  809. [4, 36, 16, 4, 37, 17],
  810. [4, 36, 12, 4, 37, 13],
  811. [2, 86, 68, 2, 87, 69],
  812. [4, 69, 43, 1, 70, 44],
  813. [6, 43, 19, 2, 44, 20],
  814. [6, 43, 15, 2, 44, 16],
  815. [4, 101, 81],
  816. [1, 80, 50, 4, 81, 51],
  817. [4, 50, 22, 4, 51, 23],
  818. [3, 36, 12, 8, 37, 13],
  819. [2, 116, 92, 2, 117, 93],
  820. [6, 58, 36, 2, 59, 37],
  821. [4, 46, 20, 6, 47, 21],
  822. [7, 42, 14, 4, 43, 15],
  823. [4, 133, 107],
  824. [8, 59, 37, 1, 60, 38],
  825. [8, 44, 20, 4, 45, 21],
  826. [12, 33, 11, 4, 34, 12],
  827. [3, 145, 115, 1, 146, 116],
  828. [4, 64, 40, 5, 65, 41],
  829. [11, 36, 16, 5, 37, 17],
  830. [11, 36, 12, 5, 37, 13],
  831. [5, 109, 87, 1, 110, 88],
  832. [5, 65, 41, 5, 66, 42],
  833. [5, 54, 24, 7, 55, 25],
  834. [11, 36, 12],
  835. [5, 122, 98, 1, 123, 99],
  836. [7, 73, 45, 3, 74, 46],
  837. [15, 43, 19, 2, 44, 20],
  838. [3, 45, 15, 13, 46, 16],
  839. [1, 135, 107, 5, 136, 108],
  840. [10, 74, 46, 1, 75, 47],
  841. [1, 50, 22, 15, 51, 23],
  842. [2, 42, 14, 17, 43, 15],
  843. [5, 150, 120, 1, 151, 121],
  844. [9, 69, 43, 4, 70, 44],
  845. [17, 50, 22, 1, 51, 23],
  846. [2, 42, 14, 19, 43, 15],
  847. [3, 141, 113, 4, 142, 114],
  848. [3, 70, 44, 11, 71, 45],
  849. [17, 47, 21, 4, 48, 22],
  850. [9, 39, 13, 16, 40, 14],
  851. [3, 135, 107, 5, 136, 108],
  852. [3, 67, 41, 13, 68, 42],
  853. [15, 54, 24, 5, 55, 25],
  854. [15, 43, 15, 10, 44, 16],
  855. [4, 144, 116, 4, 145, 117],
  856. [17, 68, 42],
  857. [17, 50, 22, 6, 51, 23],
  858. [19, 46, 16, 6, 47, 17],
  859. [2, 139, 111, 7, 140, 112],
  860. [17, 74, 46],
  861. [7, 54, 24, 16, 55, 25],
  862. [34, 37, 13],
  863. [4, 151, 121, 5, 152, 122],
  864. [4, 75, 47, 14, 76, 48],
  865. [11, 54, 24, 14, 55, 25],
  866. [16, 45, 15, 14, 46, 16],
  867. [6, 147, 117, 4, 148, 118],
  868. [6, 73, 45, 14, 74, 46],
  869. [11, 54, 24, 16, 55, 25],
  870. [30, 46, 16, 2, 47, 17],
  871. [8, 132, 106, 4, 133, 107],
  872. [8, 75, 47, 13, 76, 48],
  873. [7, 54, 24, 22, 55, 25],
  874. [22, 45, 15, 13, 46, 16],
  875. [10, 142, 114, 2, 143, 115],
  876. [19, 74, 46, 4, 75, 47],
  877. [28, 50, 22, 6, 51, 23],
  878. [33, 46, 16, 4, 47, 17],
  879. [8, 152, 122, 4, 153, 123],
  880. [22, 73, 45, 3, 74, 46],
  881. [8, 53, 23, 26, 54, 24],
  882. [12, 45, 15, 28, 46, 16],
  883. [3, 147, 117, 10, 148, 118],
  884. [3, 73, 45, 23, 74, 46],
  885. [4, 54, 24, 31, 55, 25],
  886. [11, 45, 15, 31, 46, 16],
  887. [7, 146, 116, 7, 147, 117],
  888. [21, 73, 45, 7, 74, 46],
  889. [1, 53, 23, 37, 54, 24],
  890. [19, 45, 15, 26, 46, 16],
  891. [5, 145, 115, 10, 146, 116],
  892. [19, 75, 47, 10, 76, 48],
  893. [15, 54, 24, 25, 55, 25],
  894. [23, 45, 15, 25, 46, 16],
  895. [13, 145, 115, 3, 146, 116],
  896. [2, 74, 46, 29, 75, 47],
  897. [42, 54, 24, 1, 55, 25],
  898. [23, 45, 15, 28, 46, 16],
  899. [17, 145, 115],
  900. [10, 74, 46, 23, 75, 47],
  901. [10, 54, 24, 35, 55, 25],
  902. [19, 45, 15, 35, 46, 16],
  903. [17, 145, 115, 1, 146, 116],
  904. [14, 74, 46, 21, 75, 47],
  905. [29, 54, 24, 19, 55, 25],
  906. [11, 45, 15, 46, 46, 16],
  907. [13, 145, 115, 6, 146, 116],
  908. [14, 74, 46, 23, 75, 47],
  909. [44, 54, 24, 7, 55, 25],
  910. [59, 46, 16, 1, 47, 17],
  911. [12, 151, 121, 7, 152, 122],
  912. [12, 75, 47, 26, 76, 48],
  913. [39, 54, 24, 14, 55, 25],
  914. [22, 45, 15, 41, 46, 16],
  915. [6, 151, 121, 14, 152, 122],
  916. [6, 75, 47, 34, 76, 48],
  917. [46, 54, 24, 10, 55, 25],
  918. [2, 45, 15, 64, 46, 16],
  919. [17, 152, 122, 4, 153, 123],
  920. [29, 74, 46, 14, 75, 47],
  921. [49, 54, 24, 10, 55, 25],
  922. [24, 45, 15, 46, 46, 16],
  923. [4, 152, 122, 18, 153, 123],
  924. [13, 74, 46, 32, 75, 47],
  925. [48, 54, 24, 14, 55, 25],
  926. [42, 45, 15, 32, 46, 16],
  927. [20, 147, 117, 4, 148, 118],
  928. [40, 75, 47, 7, 76, 48],
  929. [43, 54, 24, 22, 55, 25],
  930. [10, 45, 15, 67, 46, 16],
  931. [19, 148, 118, 6, 149, 119],
  932. [18, 75, 47, 31, 76, 48],
  933. [34, 54, 24, 34, 55, 25],
  934. [20, 45, 15, 61, 46, 16]
  935. ];
  936. QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
  937. var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
  938. if (rsBlock == undefined) {
  939. throw new Error(
  940. "bad rs block @ typeNumber:" +
  941. typeNumber +
  942. "/errorCorrectLevel:" +
  943. errorCorrectLevel
  944. );
  945. }
  946. var length = rsBlock.length / 3;
  947. var list = [];
  948. for (var i = 0; i < length; i++) {
  949. var count = rsBlock[i * 3 + 0];
  950. var totalCount = rsBlock[i * 3 + 1];
  951. var dataCount = rsBlock[i * 3 + 2];
  952. for (var j = 0; j < count; j++) {
  953. list.push(new QRRSBlock(totalCount, dataCount));
  954. }
  955. }
  956. return list;
  957. };
  958. QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
  959. switch (errorCorrectLevel) {
  960. case QRErrorCorrectLevel.L:
  961. return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
  962. case QRErrorCorrectLevel.M:
  963. return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
  964. case QRErrorCorrectLevel.Q:
  965. return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
  966. case QRErrorCorrectLevel.H:
  967. return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
  968. default:
  969. return undefined;
  970. }
  971. };
  972. function QRBitBuffer() {
  973. this.buffer = [];
  974. this.length = 0;
  975. }
  976. QRBitBuffer.prototype = {
  977. get: function(index) {
  978. var bufIndex = Math.floor(index / 8);
  979. return ((this.buffer[bufIndex] >>> (7 - (index % 8))) & 1) == 1;
  980. },
  981. put: function(num, length) {
  982. for (var i = 0; i < length; i++) {
  983. this.putBit(((num >>> (length - i - 1)) & 1) == 1);
  984. }
  985. },
  986. getLengthInBits: function() {
  987. return this.length;
  988. },
  989. putBit: function(bit) {
  990. var bufIndex = Math.floor(this.length / 8);
  991. if (this.buffer.length <= bufIndex) {
  992. this.buffer.push(0);
  993. }
  994. if (bit) {
  995. this.buffer[bufIndex] |= 0x80 >>> this.length % 8;
  996. }
  997. this.length++;
  998. }
  999. };
  1000. var QRCodeLimitLength = [
  1001. [17, 14, 11, 7],
  1002. [32, 26, 20, 14],
  1003. [53, 42, 32, 24],
  1004. [78, 62, 46, 34],
  1005. [106, 84, 60, 44],
  1006. [134, 106, 74, 58],
  1007. [154, 122, 86, 64],
  1008. [192, 152, 108, 84],
  1009. [230, 180, 130, 98],
  1010. [271, 213, 151, 119],
  1011. [321, 251, 177, 137],
  1012. [367, 287, 203, 155],
  1013. [425, 331, 241, 177],
  1014. [458, 362, 258, 194],
  1015. [520, 412, 292, 220],
  1016. [586, 450, 322, 250],
  1017. [644, 504, 364, 280],
  1018. [718, 560, 394, 310],
  1019. [792, 624, 442, 338],
  1020. [858, 666, 482, 382],
  1021. [929, 711, 509, 403],
  1022. [1003, 779, 565, 439],
  1023. [1091, 857, 611, 461],
  1024. [1171, 911, 661, 511],
  1025. [1273, 997, 715, 535],
  1026. [1367, 1059, 751, 593],
  1027. [1465, 1125, 805, 625],
  1028. [1528, 1190, 868, 658],
  1029. [1628, 1264, 908, 698],
  1030. [1732, 1370, 982, 742],
  1031. [1840, 1452, 1030, 790],
  1032. [1952, 1538, 1112, 842],
  1033. [2068, 1628, 1168, 898],
  1034. [2188, 1722, 1228, 958],
  1035. [2303, 1809, 1283, 983],
  1036. [2431, 1911, 1351, 1051],
  1037. [2563, 1989, 1423, 1093],
  1038. [2699, 2099, 1499, 1139],
  1039. [2809, 2213, 1579, 1219],
  1040. [2953, 2331, 1663, 1273]
  1041. ];
  1042. // QRCode object
  1043. QRCode = function(canvasId, vOption) {
  1044. this._htOption = {
  1045. width: 256,
  1046. height: 256,
  1047. typeNumber: 4,
  1048. colorDark: "#000000",
  1049. colorLight: "#ffffff",
  1050. correctLevel: QRErrorCorrectLevel.H
  1051. };
  1052. if (typeof vOption === "string") {
  1053. vOption = {
  1054. text: vOption
  1055. };
  1056. }
  1057. // Overwrites options
  1058. if (vOption) {
  1059. for (var i in vOption) {
  1060. this._htOption[i] = vOption[i];
  1061. }
  1062. }
  1063. this._oQRCode = null;
  1064. this.canvasId = canvasId;
  1065. if (this._htOption.text && this.canvasId) {
  1066. this.makeCode(this._htOption.text);
  1067. }
  1068. };
  1069. QRCode.prototype.makeCode = function(sText) {
  1070. this._oQRCode = new QRCodeModel(
  1071. _getTypeNumber(sText, this._htOption.correctLevel),
  1072. this._htOption.correctLevel
  1073. );
  1074. this._oQRCode.addData(sText);
  1075. this._oQRCode.make();
  1076. this.makeImage();
  1077. };
  1078. QRCode.prototype.makeImage = function() {
  1079. var _oContext;
  1080. if (this._htOption.usingIn) {
  1081. _oContext = wx.createCanvasContext(
  1082. this.canvasId,
  1083. this._htOption.usingIn
  1084. );
  1085. } else {
  1086. _oContext = wx.createCanvasContext(this.canvasId);
  1087. }
  1088. var _htOption = this._htOption;
  1089. var oQRCode = this._oQRCode;
  1090. var nCount = oQRCode.getModuleCount();
  1091. var nWidth = _htOption.padding
  1092. ? (_htOption.width - 2 * _htOption.padding) / nCount
  1093. : _htOption.width / nCount;
  1094. var nHeight = _htOption.padding
  1095. ? (_htOption.height - 2 * _htOption.padding) / nCount
  1096. : _htOption.height / nCount;
  1097. var nRoundedHeight = Math.round(nHeight);
  1098. var nRoundedWidth = Math.round(nWidth);
  1099. if (_htOption.image && _htOption.image != "") {
  1100. _oContext.drawImage(
  1101. _htOption.image,
  1102. 0,
  1103. 0,
  1104. _htOption.width,
  1105. _htOption.height
  1106. );
  1107. }
  1108. _oContext.setFillStyle("#fff");
  1109. _oContext.fillRect(0, 0, _htOption.width, _htOption.height);
  1110. _oContext.save();
  1111. for (var row = 0; row < nCount; row++) {
  1112. for (var col = 0; col < nCount; col++) {
  1113. var bIsDark = oQRCode.isDark(row, col);
  1114. var nLeft = _htOption.padding
  1115. ? col * nWidth + _htOption.padding
  1116. : col * nWidth;
  1117. var nTop = _htOption.padding
  1118. ? row * nHeight + _htOption.padding
  1119. : row * nHeight;
  1120. _oContext.setStrokeStyle(
  1121. bIsDark ? _htOption.colorDark : _htOption.colorLight
  1122. );
  1123. // _oContext.setStrokeStyle('red')
  1124. _oContext.setLineWidth(1);
  1125. _oContext.setFillStyle(
  1126. bIsDark ? _htOption.colorDark : _htOption.colorLight
  1127. );
  1128. // _oContext.setFillStyle('red')
  1129. // if (bIsDark) {
  1130. _oContext.fillRect(nLeft, nTop, nWidth, nHeight);
  1131. // }
  1132. // 안티 앨리어싱 방지 처리
  1133. // if (bIsDark) {
  1134. _oContext.strokeRect(
  1135. Math.floor(nLeft) + 0.5,
  1136. Math.floor(nTop) + 0.5,
  1137. nRoundedHeight
  1138. );
  1139. _oContext.strokeRect(
  1140. Math.ceil(nLeft) - 0.5,
  1141. Math.ceil(nTop) - 0.5,
  1142. nRoundedWidth,
  1143. nRoundedHeight
  1144. );
  1145. // }
  1146. // _oContext.fillRect(
  1147. // Math.floor(nLeft) + 0.5,
  1148. // Math.floor(nTop) + 0.5,
  1149. // nRoundedWidth,
  1150. // nRoundedHeight
  1151. // );
  1152. // _oContext.fillRect(
  1153. // Math.ceil(nLeft) - 0.5,
  1154. // Math.ceil(nTop) - 0.5,
  1155. // nRoundedWidth,
  1156. // nRoundedHeight
  1157. // );
  1158. // _oContext.clearRect(
  1159. // Math.floor(nLeft) + 0.5,
  1160. // Math.floor(nTop) + 0.5,
  1161. // nRoundedWidth,
  1162. // nRoundedHeight
  1163. // );
  1164. // _oContext.clearRect(
  1165. // Math.ceil(nLeft) - 0.5,
  1166. // Math.ceil(nTop) - 0.5,
  1167. // nRoundedWidth,
  1168. // nRoundedHeight
  1169. // );
  1170. }
  1171. }
  1172. _oContext.draw(false, () => {
  1173. setTimeout(() => {
  1174. this.exportImage();
  1175. }, 800);
  1176. });
  1177. };
  1178. // 保存为图片,将临时路径传给回调
  1179. QRCode.prototype.exportImage = function(callback) {
  1180. if (
  1181. this._htOption.callback &&
  1182. typeof this._htOption.callback === "function"
  1183. ) {
  1184. wx.canvasToTempFilePath({
  1185. x: 0,
  1186. y: 0,
  1187. width: this._htOption.width,
  1188. height: this._htOption.height,
  1189. destWidth: this._htOption.width,
  1190. destHeight: this._htOption.height,
  1191. canvasId: this.canvasId,
  1192. success: res => {
  1193. this._htOption.callback({
  1194. path: res.tempFilePath
  1195. });
  1196. }
  1197. });
  1198. }
  1199. };
  1200. QRCode.CorrectLevel = QRErrorCorrectLevel;
  1201. })();
  1202. module.exports = QRCode;