From ebfaff5199c33becd1bb350306f4fbdbc0204906 Mon Sep 17 00:00:00 2001 From: Dimitar Kerezov Date: Wed, 10 May 2017 17:38:10 +0300 Subject: [PATCH] Use qr-image for qr code generation --- package.json | 2 ++ services/qr.ts | 58 ++++++++----------------------------------- static-config-base.ts | 2 +- 3 files changed, 14 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index f4a0a2f4..8622f7d8 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "progress-stream": "0.5.0", "properties-parser": "0.2.3", "pullstream": "https://github.com/icenium/node-pullstream/tarball/master", + "qr-image": "3.2.0", "qrcode-generator": "1.0.0", "request": "2.81.0", "rimraf": "2.2.6", @@ -74,6 +75,7 @@ "@types/chai": "3.4.34", "@types/chai-as-promised": "0.0.29", "@types/node": "6.0.61", + "@types/qr-image": "3.2.0", "@types/request": "0.0.42", "@types/semver": "5.3.30", "@types/source-map": "0.5.0", diff --git a/services/qr.ts b/services/qr.ts index 0c15478d..ae25b8db 100644 --- a/services/qr.ts +++ b/services/qr.ts @@ -1,56 +1,20 @@ -let qrcode = require("qrcode-generator"); +import { imageSync } from "qr-image"; +import { escape } from "querystring"; export class QrCodeGenerator implements IQrCodeGenerator { - // The order is important. - private static ERROR_CORRECTION_LEVEL = ["L", "M", "Q", "H"]; - - // https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders/Additional_information - private static MAX_BLOCK_VERSION = 40; - - constructor(private $staticConfig: Config.IStaticConfig) { } - - public async generateQrCode(data: string): Promise { - let errorCorrectionLevel = "L"; - let errorCorrectionOffset = _.indexOf(QrCodeGenerator.ERROR_CORRECTION_LEVEL, errorCorrectionLevel); - - // 4 is from the qrcode-generator source code. - let maxReedSolomonBlockIndex = QrCodeGenerator.MAX_BLOCK_VERSION / 4 - errorCorrectionOffset; - - for (let i = 1; i <= maxReedSolomonBlockIndex; ++i) { - let qr = qrcode(i, errorCorrectionLevel); - try { - qr.addData(data); - qr.make(); - } catch (ex) { - let expected = "code length overflow."; - if (ex.message && ex.message.substr(0, expected.length) === expected) { - continue; - } else { - throw ex; - } - } - - return qr; - } - - // 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. - // Return null and expect the consumer to take caution in handling this case - return null; - } + constructor(private $staticConfig: Config.IStaticConfig, + private $logger: ILogger) { } public async generateDataUri(data: string): Promise { - let qr = await this.generateQrCode(data); - let dataUri: string = null; - if (qr) { - let cells = qr.getModuleCount(); - let size = this.$staticConfig.QR_SIZE; - let cellSize = Math.ceil(size / (cells + 2 * 4 /* margin */)); - - let imgTag = qr.createImgTag(cellSize); - dataUri = imgTag.split('src="')[1].split('"')[0]; + let result: string = null; + try { + const qrSvg = imageSync(data, { size: this.$staticConfig.QR_SIZE, type: "svg" }).toString(); + result = `data:image/svg+xml;utf-8,${escape(qrSvg)}`; + } catch (err) { + this.$logger.trace(`Failed to generate QR code for ${data}`, err); } - return dataUri; + return result; } } diff --git a/static-config-base.ts b/static-config-base.ts index 1cd52335..065e5599 100644 --- a/static-config-base.ts +++ b/static-config-base.ts @@ -11,7 +11,7 @@ export class StaticConfigBase implements Config.IStaticConfig { public ERROR_REPORT_SETTING_NAME: string = null; public APP_RESOURCES_DIR_NAME = "App_Resources"; public COMMAND_HELP_FILE_NAME = 'command-help.json'; - public QR_SIZE = 300; + public QR_SIZE = 5; public RESOURCE_DIR_PATH = __dirname; public SYS_REQUIREMENTS_LINK: string; public HTML_CLI_HELPERS_DIR: string;