test - 副本 (2).cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. #include "StdAfx.h"
  2. #include "BatchService.h"
  3. #include "scan_common.h"
  4. #include "..\EvaluationUtil\HttpClient.h"
  5. #include "..\Schema\schema_struct.h"
  6. #include "SchemaLoader.h"
  7. #include "basic_struct_result.h"
  8. #include "..\Identifier\schema_struct.h"
  9. #include "ServerConfig.h"
  10. //#include "Log4cplusInitalizer.h"
  11. #include "TemplateManager.h"
  12. #include "resource.h"
  13. #include "IdentifyService.h"
  14. #include "ResultUploader.h"
  15. #include <direct.h>
  16. #include <time.h>
  17. #include "OnlineCardIdentifyService.h"
  18. #include <fstream>
  19. #include "../Identifier/OnLineCardSchemaStruct.h"
  20. #include "..\ZLibWrapMemLib\UnZipFile.h"
  21. #include "..\ZLibWrapMemLib\MemZipFile.h"
  22. #include "..\ZLibWrapLib\ZLibWrapLib.h"
  23. #include "OnlineCardStudentMatcher.h"
  24. #include "ResultUploader.h"
  25. #include <future>
  26. #include "../Identifier/PageIdentify.h"
  27. int m_nSubjectID = 0;
  28. CString GetExePath();
  29. CString AnsiToUnicode(const std::string& str);
  30. std::string UnicodeToAnsi(const CString& str);
  31. using namespace schema;
  32. using namespace OnLineCard;
  33. OnLineCard::PaperTemplate* m_onlineCardTemplate = new OnLineCard::PaperTemplate;
  34. struct saveImgesPara1{
  35. vector<CUT_AREA_RESULT*> *area_rst;
  36. CString path;
  37. int subjectID;
  38. bool flag;
  39. //int ID;
  40. saveImgesPara1(vector<CUT_AREA_RESULT*> *area_rst1, CString name1, int subjectid, bool flag1) : path(name1), subjectID(subjectid), flag(flag1)
  41. {
  42. area_rst = area_rst1;
  43. //ID = id;
  44. //printf("name: %s \r\n ", (*area_rst)[0]->area_name.c_str());
  45. }
  46. };
  47. bool ParseTemplateFromJsonAll(const std::string&fileName)//全学科在线答题卡
  48. {
  49. extern bool g_isAllSubject;//是否是全学科
  50. g_isAllSubject = 1;
  51. //1 单选 2 小题单选 3 多选 4 小题多选 5 单空 6 多空 7 小题多空 8 解答 9 小题解答 10 英语作文 11 语文作文 12 判断题
  52. //0选择 1解答 2选作 3填空 4编组 5不定项 8不定项
  53. map<string, int> type_map;//新旧题型对应
  54. type_map["1"] = 0; type_map["2"] = 0; type_map["3"] = 5; type_map["4"] = 5; type_map["5"] = 3; type_map["6"] = 3;
  55. type_map["7"] = 3; type_map["8"] = 1; type_map["9"] = 1; type_map["12"] = 0; /*type_map["10"] = 1; type_map["11"] = 1; */
  56. CUnZipFile uzip(CString(fileName.c_str()));
  57. std::map<CString, std::vector<unsigned char>> map1;
  58. while (uzip.HasMoreEntry()){
  59. CString fileNam;
  60. uzip.GetNextEntry(fileNam);
  61. char buffer[1024 * 8];
  62. int len;
  63. std::vector<unsigned char>& data = map1[fileNam];
  64. data.reserve(1024 * 128);
  65. while ((len = uzip.Read(buffer, 1024 * 8)) > 0){
  66. if (data.capacity() < data.size() + len){
  67. int c = data.capacity() + 1024 * 128;
  68. data.reserve(c);
  69. }
  70. int oldSize = data.size();
  71. data.resize(oldSize + len);
  72. char * dst = (char *)data.data() + oldSize;
  73. memcpy(dst, buffer, len);
  74. }
  75. }
  76. uzip.Close();
  77. auto schemabytes = map1.find(_T("json.txt"));
  78. if (schemabytes == map1.end()){
  79. return SCH_LOAD_ERR_MISSINGFORMAT;
  80. }
  81. std::vector<unsigned char>& data = schemabytes->second;
  82. auto strJson = std::string((char *)data.data(), data.size());
  83. if (!m_onlineCardTemplate) return false;
  84. m_onlineCardTemplate->pages.clear();
  85. auto pfGetPos = [](const rapidjson::Value&value)->std::tuple<bool, Pos>{
  86. bool bRet = false;
  87. double x = 0.0, y = 0.0, w = 0.0, h = 0.0;
  88. auto itX = value.FindMember("x");
  89. if (itX != value.MemberEnd() && (itX->value.IsInt() || itX->value.IsDouble())){
  90. x = itX->value.GetDouble();
  91. }
  92. auto itY = value.FindMember("y");
  93. if (itY != value.MemberEnd() && (itY->value.IsInt() || itY->value.IsDouble())){
  94. y = itY->value.GetDouble();
  95. }
  96. auto itW = value.FindMember("width");
  97. if (itW != value.MemberEnd() && (itW->value.IsInt() || itW->value.IsDouble())){
  98. w = itW->value.GetDouble();
  99. }
  100. auto itH = value.FindMember("height");
  101. if (itH != value.MemberEnd() && (itH->value.IsInt() || itH->value.IsDouble())){
  102. h = itH->value.GetDouble();
  103. bRet = true;
  104. }
  105. return std::tie(bRet, Pos{ x, y, w, h });
  106. };
  107. rapidjson::Document doc;
  108. doc.Parse(strJson.c_str());
  109. if (doc.HasParseError()) return false;
  110. m_onlineCardTemplate->subject_id = m_nSubjectID;
  111. m_onlineCardTemplate->_version = "3.1.0";
  112. // 检测版本号
  113. auto it_version = doc.FindMember("online_card_version");
  114. if (it_version != doc.MemberEnd() && it_version->value.IsString()){
  115. m_onlineCardTemplate->_version = it_version->value.GetString();
  116. }
  117. LOGFMTI("在线答题卡版本号:%s", m_onlineCardTemplate->_version.c_str());
  118. {
  119. // 总页数
  120. auto itTotalPage = doc.FindMember("totalPage");
  121. if (itTotalPage != doc.MemberEnd() && itTotalPage->value.IsInt()){
  122. m_onlineCardTemplate->totalPage = itTotalPage->value.GetInt();
  123. }
  124. // 是否使用二维码
  125. auto itUseQrCode = doc.FindMember("useQrCode");
  126. if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsBool()){
  127. m_onlineCardTemplate->useQrCode = itUseQrCode->value.GetBool();
  128. }
  129. if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsInt()){
  130. m_onlineCardTemplate->useQrCode = (itUseQrCode->value.GetInt() != 0);
  131. }
  132. // 学校状态
  133. auto itSchoolStatus = doc.FindMember("school_card_status");
  134. if (itSchoolStatus != doc.MemberEnd() && itSchoolStatus->value.IsInt()){
  135. m_onlineCardTemplate->schoolCardStatus = itSchoolStatus->value.GetInt();
  136. }
  137. int n_duo_xuanti_index = 0;
  138. std::string temp_all_id = "";
  139. // 页
  140. auto itPages = doc.FindMember("pages");
  141. if (itPages != doc.MemberEnd() && itPages->value.IsArray()/* && itPages->value.Size() == m_onlineCardTemplate->totalPage*/){
  142. for (auto itPage = itPages->value.Begin(); itPage != itPages->value.End(); ++itPage){
  143. if (!itPage->IsObject()) return false;
  144. PageTemplate page;
  145. // 页号
  146. auto itPageNo = itPage->FindMember("pageNo");
  147. if (itPageNo != itPage->MemberEnd() && itPageNo->value.IsInt()){
  148. page.pageNo = itPageNo->value.GetInt();
  149. }
  150. else {
  151. return false;
  152. }
  153. // 定位点
  154. auto itLocations = itPage->FindMember("location");
  155. if (itLocations != itPage->MemberEnd() && itLocations->value.IsArray()){
  156. for (auto it = itLocations->value.Begin(); it != itLocations->value.End(); ++it){
  157. Location lc;
  158. auto itType = it->FindMember("type");
  159. if (itType != it->MemberEnd() && itType->value.IsInt()){
  160. lc.type = itType->value.GetInt();
  161. }
  162. auto tm = pfGetPos(*it);
  163. if (std::get<0>(tm)){
  164. lc.pos = std::get<1>(tm);
  165. }
  166. page.location.push_back(lc);
  167. }
  168. }
  169. if (page.pageNo == 1){
  170. if (!m_onlineCardTemplate->useQrCode){
  171. // 条形码
  172. auto itBar = itPage->FindMember("studentcode_bar");
  173. if (itBar != itPage->MemberEnd() && itBar->value.IsObject()){
  174. auto itObj = itBar->value.FindMember("object");
  175. if (itObj != itBar->value.MemberEnd() && itObj->value.IsObject()){
  176. auto t = pfGetPos(itObj->value);
  177. page.studentcode_bar = std::get<1>(t);
  178. }
  179. }
  180. // 填涂考号
  181. auto itFill = itPage->FindMember("studentcode_fill");
  182. if (itFill != itPage->MemberEnd() && itFill->value.IsObject()){
  183. auto itObj = itFill->value.FindMember("object");
  184. if (itObj != itFill->value.MemberEnd() && itObj->value.IsArray()){
  185. for (auto itRow = itObj->value.Begin(); itRow != itObj->value.End(); ++itRow){
  186. auto itGroup = itRow->FindMember("group");
  187. if (itGroup != itRow->MemberEnd() && itGroup->value.IsArray()){
  188. std::vector<Opt> _vctOpt;
  189. for (auto itCol = itGroup->value.Begin(); itCol != itGroup->value.End(); ++itCol){
  190. Opt opt;
  191. auto itOptName = itCol->FindMember("optName");
  192. if (itOptName != itCol->MemberEnd() && itOptName->value.IsInt())
  193. opt.optName = std::to_string(itOptName->value.GetInt());
  194. auto t = pfGetPos(*itCol);
  195. if (std::get<0>(t))
  196. opt.pos = std::get<1>(t);
  197. _vctOpt.push_back(opt);
  198. }
  199. page.studentcode_fill.push_back(_vctOpt);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. // 缺考标记
  206. auto itAbsent = itPage->FindMember("absent");
  207. if (itAbsent != itPage->MemberEnd() && itAbsent->value.IsObject()){
  208. auto t = pfGetPos(itAbsent->value);
  209. if (std::get<0>(t)){
  210. page.absent = std::get<1>(t);
  211. }
  212. }
  213. // 二维码
  214. auto itQrCode = itPage->FindMember("QrCode");
  215. if (itQrCode != itPage->MemberEnd() && itQrCode->value.IsObject()){
  216. auto t = pfGetPos(itQrCode->value);
  217. if (std::get<0>(t)){
  218. page.QrCode = std::get<1>(t);
  219. }
  220. }
  221. } // end if page.pageNo == 0
  222. // 长宽
  223. auto itImge = itPage->FindMember("imge");
  224. if (itImge != itPage->MemberEnd()){
  225. auto t = std::get<1>(pfGetPos(itImge->value));
  226. page.w = t.w;
  227. page.h = t.h;
  228. }
  229. else{
  230. return false;
  231. }
  232. // 题目
  233. auto itQuestion = itPage->FindMember("questions");
  234. if (itQuestion != itPage->MemberEnd() && itQuestion->value.IsArray())
  235. {
  236. for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it)
  237. {
  238. question q;
  239. // 题目类型
  240. auto itType = it->FindMember("type");
  241. string qType = "1";
  242. if (itType != it->MemberEnd() && itType->value.IsString())
  243. {
  244. qType = itType->value.GetString();
  245. if (type_map.find(qType) != type_map.end())
  246. {
  247. q.type = type_map[qType];
  248. }
  249. }
  250. else if (itType != it->MemberEnd() && itType->value.IsInt())
  251. {
  252. qType = to_string(itType->value.GetInt());
  253. if (type_map.find(qType) != type_map.end())
  254. {
  255. q.type = type_map[qType];
  256. }
  257. }
  258. else
  259. {
  260. return false;
  261. }
  262. q.marktype = 0;
  263. // 题目类型
  264. auto itMarktype = it->FindMember("marktype");
  265. if (itMarktype != it->MemberEnd() && itMarktype->value.IsInt()){
  266. q.marktype = itMarktype->value.GetInt();
  267. }
  268. if (qType == "10")//英文作文
  269. {
  270. q.marktype = 10;
  271. q.type = 1;
  272. }
  273. else if (qType == "11")//语文作文
  274. {
  275. q.marktype = 4;
  276. q.type = 1;
  277. }
  278. else if (qType == "12")//判断
  279. {
  280. q.type = 0;
  281. }
  282. // 分数
  283. auto itScore = it->FindMember("score");
  284. if (itScore != it->MemberEnd() && itScore->value.IsObject()){
  285. auto itFull = itScore->value.FindMember("full");
  286. if (itFull != itScore->value.MemberEnd() && (itFull->value.IsDouble() || itFull->value.IsInt()))
  287. q.score = itFull->value.GetDouble();
  288. else if (itFull != itScore->value.MemberEnd() && itFull->value.IsString())
  289. q.score = atof(itFull->value.GetString());
  290. }
  291. // 题目编号 2选做题
  292. auto itId = it->FindMember((q.type == 2 || q.type == 4) ? "editorId" : "id");
  293. if (itId != it->MemberEnd() && itId->value.IsString()){
  294. q.id = itId->value.GetString();
  295. }
  296. if (itId != it->MemberEnd() && itId->value.IsInt()){
  297. q.id = std::to_string(itId->value.GetInt());
  298. }
  299. if (q.type == 2 || q.type == 4){
  300. auto itAllID = it->FindMember("id");
  301. if (itAllID != it->MemberEnd() && itAllID->value.IsString()){
  302. q.all_id = itAllID->value.GetString();
  303. }
  304. }
  305. auto itSmallQtNo = it->FindMember("smallQtNo");
  306. if (itSmallQtNo != it->MemberEnd() && !(itSmallQtNo->value.IsNull()))
  307. {
  308. q.smallQtNo = itSmallQtNo->value.GetInt();
  309. }
  310. else
  311. {
  312. q.smallQtNo = -1;
  313. }
  314. auto itNickID = it->FindMember("name");
  315. if (itNickID != it->MemberEnd() && !(itNickID->value.IsNull()) && itNickID->value.IsString())
  316. {
  317. //m_mapKeguantiNickName[q.id] = itNickID->value.GetString();
  318. }
  319. // 打分区域
  320. auto itScoreBox = it->FindMember("scorebox");
  321. if (itScoreBox != it->MemberEnd() && itScoreBox->value.IsObject()){
  322. // 打分框类型
  323. auto itType = itScoreBox->value.FindMember("type");
  324. if (itType != itScoreBox->value.MemberEnd() && itType->value.IsString()){
  325. q.scoreBox.type = std::stoi(itType->value.GetString());
  326. }
  327. else if (itType != itScoreBox->value.MemberEnd() && itType->value.IsInt()){
  328. q.scoreBox.type = itType->value.GetInt();
  329. }
  330. else{
  331. return false;
  332. }
  333. if (q.smallQtNo != -1)
  334. {
  335. // 小问最大分值
  336. auto itmaxScore = itScoreBox->value.FindMember("maxscore");
  337. if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsString()){
  338. q.scoreBox.maxsorce = std::stod(itmaxScore->value.GetString());
  339. }
  340. else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsDouble()){
  341. q.scoreBox.maxsorce = itScoreBox->value.GetDouble();
  342. }
  343. else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsInt()){
  344. q.scoreBox.maxsorce = itmaxScore->value.GetInt();
  345. }
  346. else{
  347. q.scoreBox.maxsorce = 0.0;
  348. }
  349. }
  350. else
  351. {
  352. q.scoreBox.maxsorce = 0.0;
  353. }
  354. // 分数上限
  355. auto itLimit = itScoreBox->value.FindMember("limit");
  356. if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsString())
  357. q.scoreBox.limit = std::stoi(itLimit->value.GetString());
  358. if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsInt())
  359. q.scoreBox.limit = itLimit->value.GetInt();
  360. // 最后一个格子是否为小数 1是 2否
  361. auto itPoint = itScoreBox->value.FindMember("point");
  362. if (itPoint != itScoreBox->value.MemberEnd()){
  363. if (itPoint->value.IsInt()){
  364. q.scoreBox.bPoint = (itPoint->value.GetInt() == 1);
  365. }
  366. else if (itPoint->value.IsString()){
  367. std::string str = itPoint->value.GetString();
  368. q.scoreBox.bPoint = (str == "1");
  369. }
  370. }
  371. // 填空题带打分
  372. if (q.scoreBox.type == 3){
  373. auto itScore = itScoreBox->value.FindMember("Score");
  374. if (itScore != itScoreBox->value.MemberEnd() && itScore->value.IsArray()){
  375. for (auto it = itScore->value.Begin(); it != itScore->value.End(); ++it){
  376. if (it->IsString()){
  377. std::string str = it->GetString();
  378. if (!str.empty())
  379. q.scoreBox.vctScore.push_back(std::stoi(str));
  380. }
  381. }
  382. }
  383. }
  384. // 打分位置
  385. auto t = pfGetPos(itScoreBox->value);
  386. if (std::get<0>(t))
  387. q.scoreBox.pos = std::get<1>(t);
  388. }
  389. // 几选几
  390. if (q.type == 2 || q.type == 4){ // 选做题
  391. rapidjson::Value::ConstMemberIterator itSel = it->FindMember("select");
  392. if (itSel != it->MemberEnd() && itSel->value.IsInt()){
  393. q.selItem = itSel->value.GetInt();
  394. }
  395. rapidjson::Value::ConstMemberIterator itTotal = it->FindMember("total");
  396. if (itTotal != it->MemberEnd() && itTotal->value.IsInt()){
  397. q.selTotal = itTotal->value.GetInt();
  398. }
  399. }
  400. // 剪裁区域
  401. if (q.type == 1 || q.type == 3 || q.type == 2 || q.type == 4){ // 1 解答题 2 选做题 3 填空题
  402. auto itCut = it->FindMember("cut");
  403. if (itCut != it->MemberEnd() && itCut->value.IsObject()){
  404. auto itLink = itCut->value.FindMember("linkparm");
  405. if (itLink != itCut->value.MemberEnd() && itLink->value.IsInt())
  406. q.cut.linkparm = itLink->value.GetInt();
  407. if (itLink != itCut->value.MemberEnd() && itLink->value.IsString())
  408. q.cut.linkparm = std::stoi(itLink->value.GetString());
  409. auto t = pfGetPos(itCut->value);
  410. if (std::get<0>(t))
  411. q.cut.pos = std::get<1>(t);
  412. if (q.type == 3 && m_onlineCardTemplate->subject_id == 8)
  413. {
  414. TCHAR FilePath[MAX_PATH];
  415. GetModuleFileName(NULL, FilePath, MAX_PATH);
  416. (_tcsrchr(FilePath, '\\'))[1] = 0;
  417. lstrcat(FilePath, _T("config.ini"));
  418. int english = GetPrivateProfileInt(_T("USER"), _T("english_height"), 30, FilePath);//英语填空题高度加大比例
  419. if (english > 0 && english <= 30)
  420. {
  421. q.cut.pos.h = q.cut.pos.h* (1.0 + english / 100.0);
  422. }
  423. }
  424. }
  425. if (q.type == 2){
  426. if (temp_all_id != q.all_id)
  427. {
  428. temp_all_id = q.all_id;
  429. n_duo_xuanti_index = 0;
  430. }
  431. if (q.cut.linkparm < 2){
  432. std::vector<std::string> split_qr;
  433. split(q.all_id, (std::string)",", &split_qr);
  434. if (n_duo_xuanti_index < split_qr.size())
  435. q.id = split_qr[n_duo_xuanti_index++];
  436. }
  437. else
  438. {
  439. std::vector<std::string> split_qr;
  440. split(q.all_id, (std::string)",", &split_qr);
  441. if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size())
  442. q.id = split_qr[n_duo_xuanti_index - 1];
  443. }
  444. }
  445. else if (q.type == 4)
  446. {
  447. if (temp_all_id != q.all_id)
  448. {
  449. temp_all_id = q.all_id;
  450. n_duo_xuanti_index = 0;
  451. }
  452. if (q.cut.linkparm < 1){
  453. std::vector<std::string> split_qr;
  454. split(q.all_id, (std::string)",", &split_qr);
  455. if (n_duo_xuanti_index < split_qr.size())
  456. q.id = split_qr[n_duo_xuanti_index++];
  457. }
  458. else
  459. {
  460. std::vector<std::string> split_qr;
  461. split(q.all_id, (std::string)",", &split_qr);
  462. if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size())
  463. q.id = split_qr[n_duo_xuanti_index - 1];
  464. }
  465. }
  466. }
  467. // 选项 单选题 多选题
  468. if (q.type == 0 || q.type == 8 || q.type == 5){
  469. auto itOpts = it->FindMember("opt");
  470. if (itOpts != it->MemberEnd() && itOpts->value.IsArray()){
  471. for (auto itOpt = itOpts->value.Begin(); itOpt != itOpts->value.End(); ++itOpt){
  472. Opt opt;
  473. auto t = pfGetPos(*itOpt);
  474. if (std::get<0>(t))
  475. opt.pos = std::get<1>(t);
  476. auto itOptName = itOpt->FindMember("optName");
  477. if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString())
  478. opt.optName = itOptName->value.GetString();
  479. q.opt.push_back(opt);
  480. }
  481. }
  482. }
  483. else if (q.type == 2 || q.type == 4){ // 选作
  484. auto itSelectqts = it->FindMember("selectqts");
  485. if (itSelectqts != it->MemberEnd() && itSelectqts->value.IsArray() && itSelectqts->value.Size() > 0){
  486. for (auto itOpt = itSelectqts->value.Begin(); itOpt != itSelectqts->value.End(); ++itOpt){
  487. Opt opt;
  488. auto t = pfGetPos(*itOpt);
  489. if (std::get<0>(t))
  490. opt.pos = std::get<1>(t);
  491. auto itOptName = itOpt->FindMember("optName");
  492. if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString())
  493. opt.optName = itOptName->value.GetString();
  494. q.opt.push_back(opt);
  495. }
  496. }
  497. }
  498. page.vctQuestions.push_back(q);
  499. }
  500. }
  501. m_onlineCardTemplate->pages.insert(std::make_pair(page.pageNo, page));
  502. }
  503. }
  504. else{
  505. return false;
  506. }
  507. }
  508. m_onlineCardTemplate->open_save_debug_img = false;
  509. m_onlineCardTemplate->dingweidian_range_top = 300; //上定位点范围
  510. m_onlineCardTemplate->dingweidian_rang_buttom = 300;// 下定位点范围
  511. m_onlineCardTemplate->dingweidian_w_max_rate = 1.0;
  512. m_onlineCardTemplate->dingweidian_h_max_rate = 1.0;
  513. m_onlineCardTemplate->dingweidian_w_min_rate = 0.7;
  514. m_onlineCardTemplate->dingweidian_h_min_rate = 0.7;
  515. //CString _ini_file = GetExePath() + _T("\\config.ini");
  516. //TCHAR sz_offset_file_name[MAX_PATH] = { 0 };
  517. //GetPrivateProfileString(_T("USER"), _T("offset_file"), _T(""), sz_offset_file_name, sizeof(sz_offset_file_name) / sizeof(TCHAR), _ini_file);
  518. //ParseTemplateOffset(UnicodeToAnsi(GetExePath() + _T("\\") + sz_offset_file_name), m_onlineCardTemplate);
  519. return true;
  520. }
  521. struct Paper_Page
  522. {
  523. string path;
  524. OMR_RESULT result;
  525. };
  526. DWORD WINAPI SaveCutImageThread(void* param)
  527. {
  528. //printf("saveImgesMy1 %p\r\n", para1);
  529. saveImgesPara1 *para = (saveImgesPara1 *)param;
  530. vector<CUT_AREA_RESULT*> *area_results = para->area_rst;
  531. CString path = para->path;
  532. bool flag = para->flag;
  533. int subjectID = para->subjectID;
  534. //printf("DST name=%s\n", (*area_results)[0]->area_name.c_str());
  535. std::string area_name;
  536. CString savePath;
  537. CFile file;
  538. if ((*area_results)[0]->area_name=="37")
  539. {
  540. int a = 1;
  541. a++;
  542. }
  543. if ((*area_results)[0]->area_name == "")
  544. {
  545. area_name = (*area_results)[0]->area_name;
  546. int idx;
  547. area_name = ((idx = area_name.find('.')) < 0) ? area_name : area_name.substr(0, idx);
  548. CString question_code;
  549. question_code.Format(_T("\\%s.jpg"), CString(area_name.c_str()));
  550. savePath = path + question_code;
  551. //printf("flag: %d , subjectID = %d,id: %d \r\n", flag?1:0, subjectID, para->ID);
  552. }
  553. else
  554. {
  555. area_name = (*area_results)[0]->area_name;
  556. CString question_code;
  557. question_code.Format(_T("\\%s.jpg"), CString(area_name.c_str()));
  558. //printf("flag: %d , subjectID = %d,id: %d \r\n", flag ? 1 : 0, subjectID, para->ID);
  559. savePath = path + question_code;
  560. }
  561. if ((*area_results).size() > 1 && (*area_results)[0]->is_cut > 0){
  562. int width = 0;
  563. int height = 0;
  564. for (int jj = 0; jj < (*area_results).size(); jj++)
  565. {
  566. if ((*area_results)[jj]->width > width)width = (*area_results)[jj]->width;
  567. height += (*area_results)[jj]->height;
  568. }
  569. cv::Mat img_big(cv::Size(width, height), CV_8UC3, cv::Scalar(255, 255, 255));
  570. for (int ii = 0, top = 0; ii < (*area_results).size(); ii++)
  571. {
  572. Mat ff = Mat(1, (*area_results)[ii]->img_data.size(), CV_8U, (*area_results)[ii]->img_data.data());
  573. Mat temp_img = imdecode(ff, CV_LOAD_IMAGE_COLOR);
  574. cv::Rect rc_tmp(0, top, temp_img.cols, temp_img.rows);
  575. Mat cut = img_big(rc_tmp);
  576. temp_img.copyTo(cut);
  577. top += temp_img.rows;
  578. }
  579. //////////////////////////////////////////////////////////////////////////
  580. vector<uchar> dst;
  581. //cv::Mat _img = cv::cvarrToMat(img);
  582. vector<int> compression_params;
  583. compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
  584. compression_params.push_back(25);
  585. imencode(".jpg", img_big, dst, compression_params);
  586. //cvResetImageROI(img);
  587. //zip.Write(&dst[0], dst.size());
  588. file.Open(savePath, CFile::modeCreate | CFile::modeWrite);
  589. file.Write(dst.data(), dst.size());
  590. file.Close();
  591. if (!(subjectID != 0) && (*area_results)[0]->is_cut == 1)
  592. {
  593. CString question_code;
  594. question_code.Format(_T("\\%sf.jpg"), CString(area_name.c_str()));
  595. savePath = path + question_code;
  596. file.Open(savePath, CFile::modeCreate | CFile::modeWrite);
  597. file.Write(dst.data(), dst.size());
  598. file.Close();
  599. //zip.PutNextEntry(question_code);
  600. //zip.Write(&dst[0], dst.size());
  601. }
  602. }
  603. else
  604. {
  605. if ((*area_results)[0]->is_cut > 0)
  606. {
  607. //zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size());
  608. if (file.Open(savePath, CFile::modeCreate | CFile::modeWrite)){
  609. file.Write((*area_results)[0]->img_data.data(), (*area_results)[0]->img_data.size());
  610. file.Close();
  611. }
  612. else{
  613. auto e = GetLastError();
  614. int n = 0; ++n;
  615. }
  616. if (!(subjectID != 0) && (*area_results)[0]->is_cut == 1)
  617. {
  618. //zip.PutNextEntry(AnsiToUnicode(area_name + "f.jpg"));
  619. //zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size());
  620. CString question_code;
  621. question_code.Format(_T("\\%sf.jpg"), CString(area_name.c_str()));
  622. savePath = path + question_code;
  623. file.Open(savePath, CFile::modeCreate | CFile::modeWrite);
  624. file.Write((*area_results)[0]->img_data.data(), (*area_results)[0]->img_data.size());
  625. file.Close();
  626. }
  627. }
  628. else
  629. {
  630. file.Open(savePath, CFile::modeCreate | CFile::modeWrite);
  631. file.Write((*area_results)[0]->img_data.data(), (*area_results)[0]->img_data.size());
  632. file.Close();
  633. //zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size());
  634. }
  635. }
  636. if (flag && (*area_results).size() > 1 && (*area_results)[0]->is_cut > 0){
  637. vector<int> compression_params_low;
  638. compression_params_low.push_back(CV_IMWRITE_JPEG_QUALITY);
  639. compression_params_low.push_back(40);
  640. vector<int> compression_params_high;
  641. compression_params_high.push_back(CV_IMWRITE_JPEG_QUALITY);
  642. compression_params_high.push_back(60);
  643. for (int jj = 0; jj < (*area_results).size(); jj++)
  644. {
  645. CString question_code;
  646. question_code.Format(_T("\\%s_%d.jpg"), CString((*area_results)[0]->area_name.c_str()), jj + 1);
  647. //zip.PutNextEntry(question_code);
  648. savePath = path + question_code;
  649. /*
  650. int width = (*area_results)[jj]->width;
  651. int height = (*area_results)[jj]->height;
  652. IplImage* img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
  653. cvSet(img, cvScalarAll(255));
  654. Mat ff = Mat(1, (*area_results)[jj]->img_data.size(), CV_8U, (*area_results)[jj]->img_data.data());
  655. Mat temp_img = imdecode(ff, CV_LOAD_IMAGE_GRAYSCALE);
  656. cvSetImageROI(img, cvRect(0, 0, temp_img.cols, temp_img.rows));
  657. cvCopy(&IplImage(temp_img), img);
  658. cvResetImageROI(img);
  659. char sz_question_code[520] = { 0 };
  660. WideCharToMultiByte(CP_ACP, 0, question_code, -1, sz_question_code, 520, NULL, NULL);
  661. vector<uchar> dst;
  662. cv::Mat _img = cv::cvarrToMat(img);
  663. if (img->height > 500){
  664. imencode(".jpg", _img, dst, compression_params_low);
  665. }
  666. else{
  667. imencode(".jpg", _img, dst, compression_params_high);
  668. }
  669. cvReleaseImage(&img);
  670. */
  671. //zip.Write(&dst[0], dst.size());
  672. file.Open(savePath, CFile::modeCreate | CFile::modeWrite);
  673. file.Write((*area_results)[jj]->img_data.data(), (*area_results)[jj]->img_data.size());
  674. file.Close();
  675. }
  676. }
  677. //printf("path:%s \r\n",CT2A(savePath));
  678. return 0;
  679. }
  680. void main()
  681. {
  682. ParseTemplateFromJsonAll("D:\\thirdNanCang\\Win32\\Debug\\1111.zip");
  683. PageIdentify identify;
  684. CvMemStorage* storage = cvCreateMemStorage(0);
  685. identify.SetTemplate(m_onlineCardTemplate);
  686. static vector<Paper_Page> pages;
  687. Paper_Page page;
  688. page.path = "D:/1测试/1在线南昌全题型/新建文件夹/202112100116_0001.jpg";
  689. pages.push_back(page);
  690. page.path = "D:/1测试/1在线南昌全题型/新建文件夹/202112100116_0002.jpg";
  691. pages.push_back(page);
  692. for (int i = 0; i < 2; i++)
  693. {
  694. OMR_RESULT *m_result_buffer = &(pages[i].result);
  695. IplImage *src = cvLoadImage(pages[i].path.c_str());
  696. IplImage * dst = NULL;
  697. SchemaPage* pschemaPage1 = NULL;
  698. std::string path = "D:/1DRAW.jpg";
  699. //LOGI("Identify_impl 1");
  700. bool ret = identify.createSchema(src, &dst, &pschemaPage1, path.c_str(), true, "m_strQrClass", 0);
  701. //LOGI("Identify_impl 2");
  702. identify.out_result = m_result_buffer;
  703. identify.omr_result = (identify::result::OMR_RESULT*)identify.out_result;
  704. SchemaPage& schemaPage = *pschemaPage1;
  705. identify.omr_result->card_qrFlag = schemaPage.qrFlag;
  706. identify.omr_result->is_same_exam_id = schemaPage.is_same_exam_id;
  707. identify.omr_result->is_front_page = schemaPage.is_front_page;
  708. identify.omr_result->is_use_qr_code = schemaPage.is_use_qr_code;
  709. identify.omr_result->examid_by_qr_code = schemaPage.examid_by_qr_code;
  710. identify.omr_result->strMagicClassId = schemaPage.paper_id;
  711. identify.omr_result->strMagicStudentId = schemaPage.student_code;
  712. /************************读取学生学号*********************************************/
  713. ret = identify.ReadStudentID(schemaPage, dst);
  714. if (ret != identify::result::IDF_SUCCESS) {
  715. if (dst != NULL)cvReleaseImage(&dst);
  716. if (pschemaPage1 != NULL)delete pschemaPage1;
  717. return;
  718. }
  719. //LOGI("Identify_impl 3");
  720. /************************查找题目定位点,准备定位数据*********************************************/
  721. ret = identify.FindQuestionLocatePoints(schemaPage, dst);
  722. if (ret != identify::result::IDF_SUCCESS) {
  723. if (dst != NULL)cvReleaseImage(&dst);
  724. cvReleaseMemStorage(&storage);
  725. if (pschemaPage1 != NULL)delete pschemaPage1;
  726. return;
  727. }
  728. /************************客观题()*********************************************/
  729. ret = identify.ReadKeGuanTi(schemaPage, dst);
  730. if (ret != identify::result::IDF_SUCCESS) {
  731. if (dst != NULL)cvReleaseImage(&dst);
  732. cvReleaseMemStorage(&storage);
  733. if (pschemaPage1 != NULL)delete pschemaPage1;
  734. return;
  735. }
  736. //LOGI("Identify_impl 4");
  737. /************************阅卷读取*************************************************/
  738. ret = identify.ReadQuestionScore(schemaPage, dst, storage);
  739. if (ret != identify::result::IDF_SUCCESS) {
  740. if (dst != NULL)cvReleaseImage(&dst);
  741. cvReleaseMemStorage(&storage);
  742. if (pschemaPage1 != NULL)delete pschemaPage1;
  743. return;
  744. }
  745. //LOGI("Identify_impl 6");
  746. /************************根据给定区域切割图片*********************************************/
  747. ret = identify.ClipImg(schemaPage, dst);
  748. if (ret != identify::result::IDF_SUCCESS) {
  749. if (dst != NULL)cvReleaseImage(&dst);
  750. cvReleaseMemStorage(&storage);
  751. if (pschemaPage1 != NULL)delete pschemaPage1;
  752. return;
  753. }
  754. //LOGI("Identify_impl 7");
  755. /************************读取缺考标记*********************************************/
  756. identify.omr_result->quekaoFlag = identify.ReadQuekaoFlag(schemaPage, dst);
  757. identify.omr_result->card_index = schemaPage.index;
  758. /*
  759. if (1){
  760. DrawSchema(dst, pschemaPage);
  761. cvSaveImage(path.c_str(), dst);
  762. }
  763. */
  764. if (dst != NULL)cvReleaseImage(&dst);
  765. cvReleaseMemStorage(&storage);
  766. if (pschemaPage1 != NULL)delete pschemaPage1;
  767. }
  768. map<string, int> cut_area_map;
  769. for (int i = 0; i < 2; i++)
  770. {
  771. OMR_RESULT *m_result_buffer = &(pages[i].result);
  772. for (int j = 0; j < m_result_buffer->cut_area_result.size(); j++)
  773. {
  774. if (cut_area_map.find(m_result_buffer->cut_area_result[j].area_name)!=cut_area_map.end())//已经生成过了
  775. {
  776. continue;
  777. }
  778. string cut_name = m_result_buffer->cut_area_result[j].area_name;
  779. vector<CUT_AREA_RESULT*>* area_rst=new vector<CUT_AREA_RESULT*>;
  780. if (cut_name=="37")
  781. {
  782. int a = 1;
  783. a++;
  784. }
  785. for (int i2 = 0; i2 < 2; i2++)
  786. {
  787. OMR_RESULT *m_result_buffer2 = &(pages[i2].result);
  788. for (int j2 = 0; j2 < m_result_buffer2->cut_area_result.size(); j2++)
  789. {
  790. if (m_result_buffer2->cut_area_result[j2].area_name == cut_name)//
  791. {
  792. area_rst->push_back(&m_result_buffer2->cut_area_result[j2]);
  793. }
  794. }
  795. }
  796. cut_area_map[cut_name] = 0;
  797. bool flag = false;
  798. if (area_rst->size() > 1)
  799. {
  800. flag = true;
  801. }
  802. saveImgesPara1 *para = new saveImgesPara1(area_rst, CString("D:/1cutimg"), 0, flag);
  803. QueueUserWorkItem(SaveCutImageThread, para, WT_EXECUTELONGFUNCTION);
  804. }
  805. }
  806. Sleep(500000);
  807. return ;
  808. }