#include "stdafx.h" #include "OnlineResultHandler.h" #include "OnlineCardIdentifor.h" #include "../EvaluationUtil/HttpClient.h" #include "ServerConfig.h" extern int g_my_scan_type; extern std::string g_strShoolID; extern int g_flagid; extern int g_schoolCardStatus; namespace OnLineCard{ static CString AnsiToUnicode(const std::string& str) { CString strRet; int nLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str.c_str(), -1, NULL, 0); if (nLen == 0){ return strRet; } wchar_t* pResult = new wchar_t[nLen]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str.c_str(), -1, pResult, nLen); strRet = pResult; delete[]pResult; return strRet; } // unicode转ANSI std::string UnicodeToAnsi(const CString& str) { std::string ret; int nLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); if (nLen == 0){ return ret; } char* pResult = new char[nLen]; WideCharToMultiByte(CP_ACP, 0, str, -1, pResult, nLen, NULL, NULL); ret = pResult; delete[] pResult; return ret; } COnlineResultHandler::COnlineResultHandler() { m_muban_page_count = 2; m_bOnlineCard = true; m_bUseQrCode = false;//是否使用二维码 m_bIdentifyQrCode = false;// 是否识别二维码 } COnlineResultHandler::~COnlineResultHandler() { } ServiceState COnlineResultHandler::OnStarting(void) { m_stop = FALSE; auto ret = __super::OnStarting(); m_bOnlineCard = true; OnLineCard::PaperTemplate* pTmp = static_cast(m_identifor)->GetTemplate(); if (pTmp){ m_bUseQrCode =pTmp->useQrCode;//是否使用二维码 } m_bIdentifyQrCode = false;// 是否识别二维码 return ret; } CString COnlineResultHandler::MarkHttpHeaderData() { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); CString ret; (_tcsrchr(FilePath, '\\'))[1] = 0; if (m_bErrorHandle){ lstrcat(FilePath, _T("paperinfo.ini")); WCHAR JSESSIONID[512]; GetPrivateProfileString(_T("paperinfo"), _T("session"), _T(""), JSESSIONID, 512, FilePath); ret = JSESSIONID; } else{ lstrcat(FilePath, _T("config.ini")); #ifndef BACK_STAGE WCHAR SIG[512]; GetPrivateProfileString(_T("SESSIONID"), _T("SIG"), _T(""), SIG, 512, FilePath); WCHAR TIME[512]; GetPrivateProfileString(_T("SESSIONID"), _T("TIME"), _T(""), TIME, 512, FilePath); WCHAR ID[512]; GetPrivateProfileString(L"SESSIONID", L"ID", L"", ID, 512, FilePath); WCHAR JSESSIONID[512]; GetPrivateProfileString(_T("SESSIONID"), _T("JSESSIONID"), _T(""), JSESSIONID, 512, FilePath); ret.Format(_T("userid=%s&time=%s&sig=%s&session=%s"), ID, TIME, SIG, JSESSIONID); #else WCHAR MYCOOK[512]; GetPrivateProfileString(_T("SESSIONID"), _T("MYCOOK"), _T(""), MYCOOK, 512, FilePath); CString ret; ret.Format(_T("%s"), MYCOOK); #endif } return ret; } int COnlineResultHandler::GetStudentInfo(CString paperIdStr, CString studentCard, int cardStatus, UnhandledPage& unhandled_page) { std::string response; CString postData; CString url; // 获取学生ID postData.Format(_T("paperIdStr=%s&studentCard=%s&cardStatus=%d"), paperIdStr, studentCard, cardStatus); url.Format(_T("%s/coachio/iointerface_v2/getStudentCard"), CServerConfig::server_url); CHttpClient httpClient; httpClient.SetSendHeader(MarkHttpHeaderData()); httpClient.HttpPost(url, postData, response); Json::Features features; Json::Reader re(features); Json::Value root; re.parse(response, root); if (root["success"].isInt() && root["success"].asInt()){ Json::Value object = root["object"]; if (object["student_id"].isString()){ unhandled_page.student_id = object["student_id"].asCString(); } } return 0; } ServiceState COnlineResultHandler::OnRunning(void) { CIdentifyTask* task = taskManager->getCurrentHandleTask(); if (task){ pUnhandledPageInfo = task->getUnhandledPageManager(); pUnhandledPageInfo->bOnlineCard = true; pUnhandledPageInfo->nSubjectID = 0; OnLineCard::PaperTemplate* pTmp = static_cast(m_identifor)->GetTemplate(); if (pTmp){ pUnhandledPageInfo->nSubjectID = pTmp->subject_id; } }else{ return stoping; } m_muban_page_count = m_identifor->GetMubanCount(); UnhandledPageInfo& unhandledPageInfo = *pUnhandledPageInfo; int handle_count_limit = (m_stop&&unhandledPageInfo.unhandled_page_count > 0) ? min(m_muban_page_count, unhandledPageInfo.unhandled_page_count) : m_muban_page_count; if (unhandledPageInfo.unhandled_page_count >= handle_count_limit){ if (m_muban_page_count > 0){ try{ LOGI("SAVE_PAPER_BEGIN"); SavePaper(handle_count_limit); LOGI("SAVE_PAPER_END"); } catch (cv::Exception&e){ for (int m = 0; m < m_muban_page_count; m++) { int page_index = (unhandledPageInfo.first_unhandled_page_index + m) % MAX_UNHANDLED_PAGE; if (pUnhandledPageInfo->bOnlineCard){ static_cast(m_identifor)->FreeResult(unhandledPageInfo.unhandled_pages[page_index].omr_result); } else{ unhandledPageInfo.result->FreeResult(unhandledPageInfo.unhandled_pages[page_index].omr_result); } } unhandledPageInfo.first_unhandled_page_index = (unhandledPageInfo.first_unhandled_page_index + m_muban_page_count) % MAX_UNHANDLED_PAGE; unhandledPageInfo.unhandled_page_count -= m_muban_page_count; // printf("SavePaper 异常:%s\n", e.what()); } } } OMR_RESULT * omr_result = static_cast(m_identifor)->GetResult(TRUE); if (omr_result == NULL){ if (unhandledPageInfo.unhandled_page_count <= 0){ return stoping; } m_stop = TRUE; return running; } LOGI("OnLineCardSavePage-BEGIN"); OnLineCardSavePage(omr_result); m_bSvePage = true; LOGI("OnLineCardSavePage-END"); return running; } //保存识别的结果到待处理存储区 int COnlineResultHandler::OnLineCardSavePage(OMR_RESULT * omr_result) { UnhandledPageInfo & unhandledPageInfo = *pUnhandledPageInfo; int index = (unhandledPageInfo.first_unhandled_page_index + unhandledPageInfo.unhandled_page_count) % MAX_UNHANDLED_PAGE; unhandledPageInfo.unhandled_page_count++; UnhandledPage& unhandled_page = unhandledPageInfo.unhandled_pages[index]; unhandled_page.identified = omr_result->identified; int page_index = unhandled_page.page_index = omr_result->card_index; unhandled_page.omr_result = omr_result; unhandled_page.student_code = ""; unhandled_page.student_id = ""; // 学生ID if (omr_result->identified && omr_result->qr_result.size() == 1 ){ bool bGetStuInfo = true; if (omr_result->qr_result[0].is_stu_id){ g_flagid = 1; unhandled_page.student_id = omr_result->qr_result[0].qr_str; //unhandled_page.student_code = unhandled_page.student_id; } else{ unhandled_page.student_code = omr_result->qr_result[0].qr_str; g_flagid = 0; if (m_bUseQr){ std::vector split_qr; split(m_strQr, (std::string)",", &split_qr); if (split_qr.size() >= 3){ std::vector _vct; split(split_qr[2], std::string("@"), &_vct); // std::to_string(m_examId) + "," + std::to_string(paper_id) + (student_code.empty() ? "" : ("," + student_code)); if (_vct.size() >= 3){ bGetStuInfo = false; unhandled_page.student_id = _vct[2]; g_flagid = 1; } } } } if (bGetStuInfo){ /* CString tmp = AnsiToUnicode(unhandled_page.student_code); GetStudentInfo(AnsiToUnicode(unhandled_page.omr_result->online_card_paperid), tmp, unhandled_page.omr_result->schoolCardStatus, unhandled_page); */ g_schoolCardStatus = unhandled_page.omr_result->schoolCardStatus; } } return 0; } #define DIV 20 static bool sort_line_by_x(const CvPoint* p1, CvPoint* p2) { return p1[0].x < p2[0].x; } static bool sort_line_by_y(const CvPoint* p1, CvPoint* p2) { return p1[0].y > p2[0].y; } void COnlineResultHandler::cutImage(IplImage* img, string strQuestionNo) { IplImage* src = cvCreateImage(cvGetSize(img), 8, 1); IplImage* dst1 = cvCreateImage(cvGetSize(src), 8, 1); IplImage* dst = cvCreateImage(cvGetSize(src), 8, 1); cvCvtColor(img, src, CV_BGR2GRAY); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* lines = 0; cvCanny(src, dst1, 50, 150, 3); lines = cvHoughLines2(dst1, storage, CV_HOUGH_PROBABILISTIC, 0.5, 0.5*CV_PI / 180, 20, 20, 3); vector pVec; vector pyVec; int iCnt = 0, iCntY = 0; for (int i = 0; i < lines->total; i++) { CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i); if (abs(line[0].x - line[1].x)<200) continue; if (abs(line[0].y - line[1].y)>5) continue; if (abs(line[0].y - src->height)<5) continue; if (abs(line[1].y - src->height)<5) continue; pVec.push_back(line); iCnt++; } for (int i = 0; i < lines->total; i++) { CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i); if (abs(line[0].y - line[1].y)<200) continue; if (abs(line[0].x - line[1].x)>5) continue; pyVec.push_back(line); iCntY++; } if (pyVec.size()>1) { sort(pyVec.begin(), pyVec.end(), sort_line_by_x);//x坐标从小到大顺序排列 } if (pVec.size()>1) { sort(pVec.begin(), pVec.end(), sort_line_by_y); } CvPoint* lineTx = NULL; int OriginX, OriginY; if (pyVec.size()>1 && pVec.size()>1) { vector::iterator itx = pyVec.end() - 1; int len1 = pyVec.size(); for (lineTx = *itx; (lineTx[0].x>src->width / 2) && (len1>0);) { len1--; if (len1>0) { itx--; lineTx = *itx; } } OriginX = lineTx[0].x + 20; CvPoint* lineTy = NULL; vector::iterator it = pVec.begin(); for (lineTy = *it; (lineTy[0].y>src->height / 2) && (it != pVec.end());) { it++; if (it != pVec.end()) lineTy = *it; } OriginY = lineTy[0].y + 50; } if (pVec.size()>1) { CvPoint* line = *(pVec.begin()); CvPoint* firstLine = *(pVec.end() - 1); int width; width = abs(line[0].x - line[1].x) - 200; int height = line[0].y - firstLine[0].y; if (widthwidth * 2 / 3) { width = src->width - 300; } int x = line[0].xsrc->width / 20) x = src->width / 20 + 50; int y; if (heightheight * 2 / 3) { height = src->height - 10; y = height; } else y = line[0].y; int iHeight = height / DIV; int cnt = 0; CvRect rc; CvRect rcS; cvThreshold(dst1, dst, 128, 255, CV_THRESH_BINARY_INV); for (int i = 1; i <= DIV; i++) { rc = cvRect(x, y - iHeight*i, width, iHeight); if (i == 1) rc.height -= 5; cnt++; int TotalNumberOfPixels = rc.width * rc.height; if (rc.width >= 0 && rc.height >= 0 && ((rc.x + rc.width)width) && ((rc.y + rc.height)height)) { cvSetImageROI(dst, rc); int iPix = TotalNumberOfPixels - cvCountNonZero(dst);//计算黑色像素数量 cvResetImageROI(dst); if (iPix<30) rcS = rc; else { rcS = rc; break; } } } if (pyVec.size()>1) { CvRect rcOnlyTitle; rcOnlyTitle.x = OriginX; rcOnlyTitle.y = OriginY; rcOnlyTitle.width = rc.width; CvPoint* lineT = *(pVec.begin()); rcOnlyTitle.height = abs(lineT[0].y - OriginY - 20); if (rcOnlyTitle.height>0) { if (rcOnlyTitle.width >= 0 && rcOnlyTitle.height >= 0 && ((rcOnlyTitle.x + rcOnlyTitle.width)width) && ((rcOnlyTitle.y + rcOnlyTitle.height)height)) { cvSetImageROI(dst, rcOnlyTitle); int TotalNumberOfPixels2 = rcOnlyTitle.width * rcOnlyTitle.height; int iPix2 = TotalNumberOfPixels2 - cvCountNonZero(dst);//计算黑色像素数量 cvResetImageROI(dst); if (iPix2<20) { int iQuestionNo = atoi(strQuestionNo.c_str()); } } } } CvRect rcR = cvRect(0, 0, dst->width, rcS.y + iHeight + 30);//rsult if ((rcR.y + rcR.height)height) cvSetImageROI(img, rcR); } cvReleaseMemStorage(&storage); cvReleaseImage(&src);//释放img所指向的内存空间 cvReleaseImage(&dst1); cvReleaseImage(&dst); } void COnlineResultHandler::SaveImages(vector &area_results, CMemZipFile &zip, int subjectID, BOOL bOnlineCard, char *strPaperCode, const std::vector &postMarkTypeIDVec, std::map &vecTwoPic) { // printf("SaveImages-begin\n"); //return __super::SaveImages(area_results, zip, strPaperCode, postMarkTypeIDVec, vecTwoPic); std::string area_name; BOOL flag = false; if (bOnlineCard && subjectID == 0) { for (int i = 0; i < postMarkTypeIDVec.size(); i++) { for (int j = 0; j < area_results.size(); j++){ if (postMarkTypeIDVec[i] == area_results[j]->area_name) { flag = true; break; } } } } if (area_results[0]->area_name == "") { area_name = area_results[0]->area_name; int idx; area_name = ((idx = area_name.find('.')) < 0) ? area_name : area_name.substr(0, idx); CString question_code; question_code.Format(_T("%s.jpg"), CString(area_name.c_str())); zip.PutNextEntry(question_code); } else { area_name = area_results[0]->area_name; CString question_code; question_code.Format(_T("%s.jpg"), CString(area_name.c_str())); zip.PutNextEntry(question_code); } if (area_results.size() > 1 && area_results[0]->is_cut > 0){ int width = 0; int height = 0; for (int jj = 0; jjwidth>width)width = area_results[jj]->width; height += area_results[jj]->height; } cv::Mat img_big(cv::Size(width, height), CV_8UC3,cv::Scalar(255,255,255)); for (int ii = 0, top = 0; ii < area_results.size(); ii++) { Mat ff = Mat(1, area_results[ii]->img_data.size(), CV_8U, area_results[ii]->img_data.data()); Mat temp_img = imdecode(ff, CV_LOAD_IMAGE_COLOR); cv::Rect rc_tmp(0, top, temp_img.cols, temp_img.rows); Mat cut = img_big(rc_tmp); temp_img.copyTo(cut); top += temp_img.rows; } ////////////////////////////////////////////////////////////////////////// vector dst; //cv::Mat _img = cv::cvarrToMat(img); vector compression_params; compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); compression_params.push_back(25); imencode(".jpg", img_big, dst, compression_params); //cvResetImageROI(img); zip.Write(&dst[0], dst.size()); if (!(bOnlineCard && subjectID != 0) && area_results[0]->is_cut == 1) { CString question_code; question_code.Format(_T("%sf.jpg"), CString(area_name.c_str())); zip.PutNextEntry(question_code); zip.Write(&dst[0], dst.size()); } } else { if (area_results[0]->is_cut > 0) { zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size()); if (!(bOnlineCard && subjectID != 0)) { zip.PutNextEntry(AnsiToUnicode(area_name + "f.jpg")); zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size()); } } else zip.Write(area_results[0]->img_data.data(), area_results[0]->img_data.size()); } if (flag && area_results.size() > 1 && area_results[0]->is_cut > 0){ vector compression_params_low; compression_params_low.push_back(CV_IMWRITE_JPEG_QUALITY); compression_params_low.push_back(40); vector compression_params_high; compression_params_high.push_back(CV_IMWRITE_JPEG_QUALITY); compression_params_high.push_back(60); for (int jj = 0; jj < area_results.size(); jj++) { CString question_code; question_code.Format(_T("%s_%d.jpg"), CString(area_results[0]->area_name.c_str()), jj + 1); zip.PutNextEntry(question_code); int width = area_results[jj]->width; int height = area_results[jj]->height; IplImage* img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); cvSet(img, cvScalarAll(255)); Mat ff = Mat(1, area_results[jj]->img_data.size(), CV_8U, area_results[jj]->img_data.data()); Mat temp_img = imdecode(ff, CV_LOAD_IMAGE_GRAYSCALE); cvSetImageROI(img, cvRect(0, 0, temp_img.cols, temp_img.rows)); cvCopy(&IplImage(temp_img), img); cvResetImageROI(img); char sz_question_code[520] = { 0 }; WideCharToMultiByte(CP_ACP, 0, question_code, -1, sz_question_code, 520, NULL, NULL); vector dst; cv::Mat _img = cv::cvarrToMat(img); if (img->height > 500){ imencode(".jpg", _img, dst, compression_params_low); } else{ imencode(".jpg", _img, dst, compression_params_high); } cvReleaseImage(&img); zip.Write(&dst[0], dst.size()); } vecTwoPic[area_results[0]->area_name.c_str()] = area_results.size(); } } }