imageOcr.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import {
  2. getInputDir,
  3. getOutputDir,
  4. makeDirSync,
  5. getImgDecodeTool,
  6. getTmpDir,
  7. getExtraDir
  8. } from "./env";
  9. import { randomCode, formatDate } from "./utils";
  10. const fs = window.nodeRequire("fs");
  11. const path = window.nodeRequire("path");
  12. const childProcess = window.nodeRequire("child_process");
  13. const gm = window.nodeRequire("gm").subClass({
  14. imageMagick: true,
  15. appPath: getExtraDir("imagemagick/")
  16. });
  17. /**
  18. * 旋转图片,并保存为正式文件
  19. * @param {*} scaningImageList 图片路径
  20. * @param {String} paperInfo 保持文件名称
  21. */
  22. export function saveOutputImage(scaningImageList, paperInfo) {
  23. console.log(scaningImageList);
  24. let outputOriginPaths = [];
  25. for (let i = 0; i < scaningImageList.length; i++) {
  26. const imagePath = scaningImageList[i];
  27. const originImageFile = saveOriginImage(imagePath, paperInfo);
  28. outputOriginPaths.push(originImageFile);
  29. fs.unlinkSync(imagePath);
  30. }
  31. return outputOriginPaths;
  32. }
  33. function saveOriginImage(imagePath, paperInfo) {
  34. console.log(imagePath);
  35. const outputDir = path.join(getOutputDir("origin"), paperInfo.taskId + "");
  36. if (!fs.existsSync(outputDir)) makeDirSync(outputDir);
  37. const outputOriginPath = path.join(outputDir, path.basename(imagePath));
  38. fs.copyFileSync(imagePath, outputOriginPath);
  39. return outputOriginPath;
  40. }
  41. /**
  42. * 获取最早添加的文件
  43. * @param {String} dir 图片目录
  44. */
  45. export function getEarliestFile(dir) {
  46. const ddir = dir || getInputDir();
  47. const files = fs
  48. .readdirSync(ddir)
  49. .filter(fileName => fileName.toLowerCase().match(/\.(jpg|png|jpeg)/))
  50. .map(fileName => {
  51. return {
  52. name: fileName,
  53. time: fs.statSync(path.join(ddir, fileName)).birthtimeMs
  54. };
  55. })
  56. .sort((a, b) => a.time - b.time);
  57. if (!files.length) return { url: "", name: "" };
  58. return {
  59. url: path.join(ddir, files[0].name),
  60. name: files[0].name
  61. };
  62. }
  63. export function getPreUploadFilesAutoSerial(dir) {
  64. const ddir = dir || getInputDir();
  65. const files = fs
  66. .readdirSync(ddir)
  67. .filter(fileName => fileName.toLowerCase().match(/\.(jpg|png|jpeg)/));
  68. let imageList = [];
  69. const len = Math.ceil(files.length / 2);
  70. for (let i = 0; i < len; i++) {
  71. const frontFile = path.join(dir, files[2 * i]);
  72. const versoFile = path.join(dir, files[2 * i + 1]);
  73. imageList.push({
  74. frontFile,
  75. versoFile
  76. });
  77. }
  78. return imageList;
  79. }
  80. export function getPreUploadFileCount(dir) {
  81. const ddir = dir || getInputDir();
  82. const files = fs
  83. .readdirSync(ddir)
  84. .filter(fileName => fileName.toLowerCase().match(/\.(jpg|png|jpeg)/));
  85. return Math.ceil(files.length / 2);
  86. }
  87. export function clearDir(dir) {
  88. fs.readdirSync(dir).forEach(file => {
  89. fs.unlinkSync(path.join(dir, file));
  90. });
  91. }
  92. export function getPreUploadFiles(dir) {
  93. const ddir = dir || getInputDir();
  94. const files = fs
  95. .readdirSync(ddir)
  96. .filter(fileName => fileName.toLowerCase().match(/\.(json)/));
  97. let imageList = [];
  98. if (!files.length) return { succeed: false, errorMsg: "当前无扫描文件!" };
  99. const fileCont = fs.readFileSync(path.join(ddir, files[0]));
  100. const fileInfo = JSON.parse(fileCont);
  101. if (!fileInfo.succeed) {
  102. return { succeed: false, errorMsg: fileInfo.errorMsg };
  103. }
  104. imageList = fileInfo.images.map(item => {
  105. return {
  106. frontFile: item.front,
  107. versoFile: item.back
  108. };
  109. });
  110. if (!imageList.length)
  111. return { succeed: false, errorMsg: "当前无扫描文件!" };
  112. return { succeed: true, data: imageList };
  113. }
  114. export function renamePreUploadJsonFile(dir) {
  115. const ddir = dir || getInputDir();
  116. const files = fs
  117. .readdirSync(ddir)
  118. .filter(fileName => fileName.toLowerCase().match(/\.(json)/));
  119. if (!files.length) return;
  120. files.forEach(file => {
  121. fs.renameSync(
  122. path.join(ddir, file),
  123. path.join(ddir, path.basename(file, ".json") + `_${randomCode(8)}.txt`)
  124. );
  125. });
  126. }
  127. /**
  128. 扫描仪返回的数据
  129. {
  130. "images": [
  131. {
  132. "duplex": true,
  133. "front": "D:/workspace/project/scan-library/test/00000001_F.jpg",
  134. "back":"D:/workspace/project/scan-library/test/00000001_B.jpg"
  135. },
  136. {
  137. "duplex": true,
  138. "front": "D:/workspace/project/scan-library/test/00000001_B.jpg",
  139. "back":"D:/workspace/project/scan-library/test/00000001_B.jpg"
  140. }
  141. ],
  142. "succeed": true,
  143. "errorMsg":"请将试卷放置到扫描仪上,再进行扫描!"
  144. }
  145. */
  146. /**
  147. * 解析图片code信息
  148. * @param {String} imgPath 图片路径
  149. * @param {Object} codeArea code所在文件区域信息
  150. */
  151. export function decodeImageCode(imgPath, codeArea) {
  152. const tmpFile = path.join(
  153. getTmpDir(),
  154. `${formatDate("YYYYMMDDHHmmss")}_${randomCode(8)}.jpg`
  155. );
  156. const imgObj = gm(imgPath);
  157. // 裁剪条形码区域
  158. imgObj.crop(codeArea.width, codeArea.height, codeArea.x, codeArea.y);
  159. // 旋转
  160. const rotate = parseInt(codeArea.rotate);
  161. if (rotate) imgObj.rotate("#FFFFFF", rotate);
  162. return new Promise((resolve, reject) => {
  163. // 写入临时文件
  164. imgObj.write(tmpFile, function(err) {
  165. if (err) {
  166. reject("条形码临时文件获取失败");
  167. return;
  168. }
  169. // 获取条形码解析工具
  170. const exec = getImgDecodeTool();
  171. // 解析条形码
  172. let code;
  173. try {
  174. const DecodeResult = childProcess.execSync(`${exec} ${tmpFile}`);
  175. const codes = DecodeResult.toString()
  176. .replace(/\r/, "")
  177. .replace(/\n/, "")
  178. .split(":");
  179. // console.dir(codes);
  180. if (codes.length <= 2) {
  181. code = codes[codes.length - 1].replace(/\s+/g, "");
  182. }
  183. } catch (e) {
  184. console.log(e);
  185. reject("解析条形码错误");
  186. return;
  187. }
  188. // 暂时不删除临时文件
  189. fs.unlink(tmpFile, () => {});
  190. resolve(code);
  191. });
  192. });
  193. }