recog.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { maxNum, minNum } from "@/utils/tool";
  2. import { abc } from "@/constants/enumerate";
  3. // recognize ---start >
  4. // 扫描数据相关
  5. // 参考:./data.json
  6. export type RecogAreaType = "absent" | "breach" | "paperType" | "question";
  7. export interface RecogOptionSize {
  8. x: number;
  9. y: number;
  10. w: number;
  11. h: number;
  12. filled: boolean;
  13. }
  14. export interface RecognizeArea {
  15. index: number;
  16. type: RecogAreaType;
  17. fillPosition: Array<{ x: number; y: number }>;
  18. fillSize: {
  19. w: number;
  20. h: number;
  21. };
  22. fillArea: { x: number; y: number; w: number; h: number };
  23. options: string[];
  24. optionSizes: RecogOptionSize[];
  25. result: string[];
  26. multiple: boolean;
  27. // 当前区域的切图
  28. sliceImg: string;
  29. }
  30. export interface RecogDataField {
  31. field: string;
  32. index: number;
  33. content: string;
  34. wrong_flag: number;
  35. fill_result: RecogDataFillResult[];
  36. type: string;
  37. rect?: [number, number, number, number];
  38. }
  39. export interface RecogDataFillResult {
  40. main_number: number;
  41. sub_number: number;
  42. // 所有试题的统一序号
  43. index?: number;
  44. single: number;
  45. fill_option: number[];
  46. suspect_flag: number;
  47. fill_position: string[];
  48. fill_size: [number, number];
  49. }
  50. export interface RecogDataType {
  51. algorithm: number;
  52. page_index: number;
  53. error_flag: number;
  54. blank_flag: number;
  55. angle: number;
  56. examNumber: RecogDataField;
  57. absent: RecogDataField;
  58. breach: RecogDataField;
  59. pageNumber: RecogDataField;
  60. paperType: RecogDataField;
  61. question: RecogDataField[];
  62. block_struct: number[];
  63. }
  64. // recognize ---end >
  65. // extends
  66. export interface RecogEditData extends RecognizeArea {
  67. areaSrc: string;
  68. [k: string]: any;
  69. }
  70. export interface ImageRecogData extends RecognizeArea {
  71. [k: string]: any;
  72. }
  73. export interface RecogBlock extends RecognizeArea {
  74. areaImg: string;
  75. fillAreaStyle: Record<string, any>;
  76. fillOptionStyles: Array<Record<string, any>>;
  77. [k: string]: any;
  78. }
  79. // functions
  80. export function parseRecogData(data: string | null) {
  81. if (!data) return null;
  82. const precogData = window.atob(data);
  83. const recogData: RecogDataType | null = precogData
  84. ? JSON.parse(precogData)
  85. : null;
  86. return recogData;
  87. }
  88. export function parseDetailSize(
  89. data: RecogDataFillResult,
  90. type: RecogAreaType,
  91. index: number,
  92. fillResult?: number[]
  93. ): RecognizeArea {
  94. const result: RecognizeArea = {
  95. index,
  96. type,
  97. fillPosition: [],
  98. fillSize: { w: 0, h: 0 },
  99. fillArea: { x: 0, y: 0, w: 0, h: 0 },
  100. options: [],
  101. optionSizes: [],
  102. result: [],
  103. multiple: false,
  104. sliceImg: "",
  105. };
  106. if (!data) return result;
  107. const fillResultList =
  108. fillResult && fillResult.length ? fillResult : data.fill_option;
  109. result.fillSize = {
  110. w: data.fill_size[0],
  111. h: data.fill_size[1],
  112. };
  113. const offsetX = data.fill_size[0] / 2;
  114. const offsetY = data.fill_size[1] / 2;
  115. result.fillPosition = data.fill_position.map((item) => {
  116. const size = item.split(",");
  117. const x = size[0] ? Number(size[0]) : 0;
  118. const y = size[1] ? Number(size[1]) : 0;
  119. return {
  120. x: x - offsetX,
  121. y: y - offsetY,
  122. };
  123. });
  124. const xs = result.fillPosition.map((item) => item.x);
  125. const maxX = maxNum(xs);
  126. const minX = minNum(xs);
  127. result.fillArea = {
  128. x: minX,
  129. y: result.fillPosition[0].y,
  130. w: maxX - minX + result.fillSize.w,
  131. h: result.fillSize.h,
  132. };
  133. result.optionSizes = result.fillPosition.map((item, index) => {
  134. let filled = false;
  135. if (type !== "paperType") {
  136. filled = fillResultList[index] === 1;
  137. }
  138. return {
  139. x: item.x - result.fillArea.x,
  140. y: item.y - result.fillArea.y,
  141. filled,
  142. ...result.fillSize,
  143. };
  144. });
  145. if (type === "question") {
  146. const options = abc.substring(0, data.fill_position.length).split("");
  147. // 空用“#”表示
  148. result.options = ["#", ...options];
  149. result.result = options.filter((r, ind) => fillResultList[ind] === 1);
  150. result.multiple = true;
  151. }
  152. return result;
  153. }