UNPKG

@waiting/idcard-reader-base

Version:
170 lines (169 loc) 6.37 kB
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}'"`; }