@waiting/idcard-reader-base
Version:
170 lines (169 loc) • 6.37 kB
JavaScript
import { join, normalize, unlinkAsync, } from '@waiting/shared-core';
import { mapTo, tap } from 'rxjs/operators';
import { run } from 'rxrunscript';
import { config } from './config';
/**
* Convert avatar bmp to png with transparent background
* Return avatar path
*/
export function handleAvatar(path) {
// magick avatar.bmp -resize x353 -fuzz 9% -transparent '#FEFEFE' avatar.png
const target = normalize(join(config.tmpDir, 'avatar-' + Math.random().toString() + '.png')).replace(/\\/ug, '/');
const src = normalize(path).replace(/\\/ug, '/');
const cmd = `magick "${src}" -resize x353 -fuzz 9% -transparent "#FEFEFE" "${target}"`;
const ret = run(cmd, null, { maxCmdLength: 4096 }).pipe(mapTo(target));
return ret;
}
/**
* Fill base info text
*/
export function handleBaseInfo(data, avatarPath, options) {
/* istanbul ignore else */
if (!data) {
throw new TypeError('base value invalid');
}
/* istanbul ignore else */
if (!options.fontHwxhei || !options.fontOcrb || !options.fontSimhei) {
throw new TypeError('font value invalid');
}
const assetsDir = join(config.appDir, 'assets');
const tpl = join(assetsDir, 'tpl.png');
const target = join(options.compositeDir, 'composite-' + Math.random().toString() + `.${options.compositeType}`)
.replace(/\\/ug, '/');
const txtColor = options.textColor;
const hwxhei = normalize(options.fontHwxhei).replace(/\\/ug, '/');
const orcb = normalize(options.fontOcrb).replace(/\\/ug, '/');
const simhei = normalize(options.fontSimhei).replace(/\\/ug, '/');
const ps = [
genParamName(data.name, txtColor, hwxhei),
genParamGender(data.genderName, txtColor, hwxhei),
genParamNation(data.nationName, txtColor, hwxhei),
genParamBirth(data.birth, txtColor, hwxhei),
genParamIdc(data.idc, txtColor, orcb),
genParamAddress(data.address, txtColor, hwxhei),
genParamRegOrg(data.regorg, txtColor, simhei),
genParamValidDate(data.startdate, data.enddate, txtColor, hwxhei),
];
const cmd = `magick ${tpl} ` + ps.join(' ')
+ ` -compose src-over "${avatarPath}" -geometry +619+125 -quality ${options.compositeQuality} -composite "${target}"`;
const ret = run(cmd, null, { maxCmdLength: 4096 }).pipe(mapTo(target), tap(() => unlinkAsync(avatarPath)));
return ret;
}
function genParamName(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
return `-fill "${txtColor}" -font "${font}" -pointsize 42 -draw "text 208,146 '${val}'"`;
}
function genParamGender(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
return `-fill "${txtColor}" -font "${font}" -pointsize 34 -draw "text 208,220 '${val}'"`;
}
function genParamNation(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
return `-fill "${txtColor}" -font "${font}" -pointsize 34 -draw "text 395,220 '${val}'"`;
}
function genParamBirth(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
const year = val.slice(0, 4);
let month = val.slice(4, 6);
let day = val.slice(6, 8);
/* istanbul ignore else */
if (month.startsWith('0')) {
month = ' ' + month[1];
}
/* istanbul ignore else */
if (day.startsWith('0')) {
day = ' ' + day[1];
}
let ret = `-fill "${txtColor}" -font "${font}" -pointsize 33 -kerning 1 -draw "text 210,295 '${year}'"`;
ret += ` -fill "${txtColor}" -font "${font}" -pointsize 33 -draw "text 350,295 '${month}'"`;
ret += ` -fill "${txtColor}" -font "${font}" -pointsize 33 -draw "text 435,295 '${day}'"`;
return ret;
}
function genParamIdc(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
return `-fill "${txtColor}" -font "${font}" -pointsize 45 -kerning 1 -draw "text 355,561 '${val}'"`;
}
function genParamAddress(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
const len = val.length;
let ret = '';
let pos = 0;
let line = '';
let lineY = 368;
const lineHeight = 50;
do {
line = retrieveAddressLine(val, pos);
if (line.length) {
ret += ` -fill "${txtColor}" -font "${font}" -pointsize 33 -kerning 3 -draw "text 208,${lineY} '${line}'"`;
pos += line.length;
lineY += lineHeight;
}
else {
break;
}
} while (pos <= len);
return ret;
}
/* 11 Chinese every line */
function retrieveAddressLine(value, startPos) {
/* istanbul ignore else */
if (value.length <= startPos) {
return '';
}
const txt = value.slice(startPos);
/* istanbul ignore else */
if (txt.length > 10) {
if (/[\d\w-]/u.test(txt.slice(11, 12))) { // p11 is number or letter
const p12 = txt.slice(12, 13);
if (p12 && /[\d\w-]/u.test(p12)) {
return txt.slice(0, 10);
}
}
}
return txt.slice(0, 11);
}
function genParamRegOrg(value, txtColor, font) {
const val = value ? value.trim() : '';
/* istanbul ignore else */
if (!val) {
throw new TypeError('value invalid');
}
return `-fill "${txtColor}" -font "${font}" -pointsize 32 -kerning 3 -draw "text 413,1138 '${val}'"`;
}
function genParamValidDate(start, end, txtColor, font) {
const p1 = start
? start.slice(0, 4) + '.' + start.slice(4, 6) + '.' + start.slice(6, 8)
: '';
/* istanbul ignore else */
if (!p1) {
throw new TypeError('value invalid');
}
const p2 = Number.isNaN(+end)
? end
: end.slice(0, 4) + '.' + end.slice(4, 6) + '.' + end.slice(6, 8);
return `-fill "${txtColor}" -font "${font}" -pointsize 32 -kerning 1.6 -draw "text 413,1215 '${p1}-${p2}'"`;
}