123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- #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<OnLineCard::COnlineCardIdentifor*>(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<OnLineCard::COnlineCardIdentifor*>(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<OnLineCard::COnlineCardIdentifor*>(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<COnlineCardIdentifor*>(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<std::string> split_qr;
- split(m_strQr, (std::string)",", &split_qr);
- if (split_qr.size() >= 3){
- std::vector<std::string> _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<CvPoint*> pVec;
- vector<CvPoint*> 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<CvPoint*>::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<CvPoint*>::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 (width<src->width * 2 / 3)
- {
- width = src->width - 300;
- }
- int x = line[0].x<line[1].x ? line[0].x : line[1].x;
- x = x + 50;
- if (x>src->width / 20)
- x = src->width / 20 + 50;
- int y;
- if (height<src->height * 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)<dst->width) && ((rc.y + rc.height)<dst->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)<dst->width) && ((rcOnlyTitle.y + rcOnlyTitle.height)<dst->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)<dst->height)
- cvSetImageROI(img, rcR);
- }
- cvReleaseMemStorage(&storage);
- cvReleaseImage(&src);//释放img所指向的内存空间
- cvReleaseImage(&dst1);
- cvReleaseImage(&dst);
- }
- void COnlineResultHandler::SaveImages(vector<CUT_AREA_RESULT*> &area_results, CMemZipFile &zip,
- int subjectID, BOOL bOnlineCard, char *strPaperCode, const std::vector<std::string> &postMarkTypeIDVec,
- std::map<std::string, int> &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; jj<area_results.size(); jj++)
- {
- if (area_results[jj]->width>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<uchar> dst;
- //cv::Mat _img = cv::cvarrToMat(img);
- vector<int> 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<int> compression_params_low;
- compression_params_low.push_back(CV_IMWRITE_JPEG_QUALITY);
- compression_params_low.push_back(40);
- vector<int> 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<uchar> 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();
- }
- }
- }
|