|
1 |
| -let qrcode = require("qrcode-generator"); |
| 1 | +import { imageSync } from "qr-image"; |
| 2 | +import { escape } from "querystring"; |
2 | 3 |
|
3 | 4 | export class QrCodeGenerator implements IQrCodeGenerator {
|
4 |
| - // The order is important. |
5 |
| - private static ERROR_CORRECTION_LEVEL = ["L", "M", "Q", "H"]; |
6 |
| - |
7 |
| - // https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders/Additional_information |
8 |
| - private static MAX_BLOCK_VERSION = 40; |
9 |
| - |
10 |
| - constructor(private $staticConfig: Config.IStaticConfig) { } |
11 |
| - |
12 |
| - public async generateQrCode(data: string): Promise<any> { |
13 |
| - let errorCorrectionLevel = "L"; |
14 |
| - let errorCorrectionOffset = _.indexOf(QrCodeGenerator.ERROR_CORRECTION_LEVEL, errorCorrectionLevel); |
15 |
| - |
16 |
| - // 4 is from the qrcode-generator source code. |
17 |
| - let maxReedSolomonBlockIndex = QrCodeGenerator.MAX_BLOCK_VERSION / 4 - errorCorrectionOffset; |
18 |
| - |
19 |
| - for (let i = 1; i <= maxReedSolomonBlockIndex; ++i) { |
20 |
| - let qr = qrcode(i, errorCorrectionLevel); |
21 |
| - try { |
22 |
| - qr.addData(data); |
23 |
| - qr.make(); |
24 |
| - } catch (ex) { |
25 |
| - let expected = "code length overflow."; |
26 |
| - if (ex.message && ex.message.substr(0, expected.length) === expected) { |
27 |
| - continue; |
28 |
| - } else { |
29 |
| - throw ex; |
30 |
| - } |
31 |
| - } |
32 |
| - |
33 |
| - return qr; |
34 |
| - } |
35 |
| - |
36 |
| - // Since the max Reed-Solomon block index was calculated before the for loop and no exception was thrown in it here the only error can be because of long project name. |
37 |
| - // Return null and expect the consumer to take caution in handling this case |
38 |
| - return null; |
39 |
| - } |
| 5 | + constructor(private $staticConfig: Config.IStaticConfig, |
| 6 | + private $logger: ILogger) { } |
40 | 7 |
|
41 | 8 | public async generateDataUri(data: string): Promise<string> {
|
42 |
| - let qr = await this.generateQrCode(data); |
43 |
| - let dataUri: string = null; |
44 |
| - if (qr) { |
45 |
| - let cells = qr.getModuleCount(); |
46 |
| - let size = this.$staticConfig.QR_SIZE; |
47 |
| - let cellSize = Math.ceil(size / (cells + 2 * 4 /* margin */)); |
48 |
| - |
49 |
| - let imgTag = qr.createImgTag(cellSize); |
50 |
| - dataUri = imgTag.split('src="')[1].split('"')[0]; |
| 9 | + let result: string = null; |
| 10 | + try { |
| 11 | + const qrSvg = imageSync(data, { size: this.$staticConfig.QR_SIZE, type: "svg" }).toString(); |
| 12 | + result = `data:image/svg+xml;utf-8,${escape(qrSvg)}`; |
| 13 | + } catch (err) { |
| 14 | + this.$logger.trace(`Failed to generate QR code for ${data}`, err); |
51 | 15 | }
|
52 | 16 |
|
53 |
| - return dataUri; |
| 17 | + return result; |
54 | 18 | }
|
55 | 19 | }
|
56 | 20 |
|
|
0 commit comments