|
@@ -494,6 +494,7 @@ void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
|
|
|
DDX_Text(pDX, IDC_EDIT_MSG, m_strMsg);
|
|
|
DDX_Text(pDX, IDC_EDIT_SCANMSG, m_strScanMsg);
|
|
|
DDX_Text(pDX, IDC_EDIT_REPEATMSG, m_strRepeatMsg);
|
|
|
+ DDX_Text(pDX, IDC_EDIT_CSVMSG, m_strCsvMsg);
|
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
|
|
@@ -505,6 +506,7 @@ BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
|
|
|
ON_MESSAGE(WM_SHOWSCANINFO, OnShowScanInfo)
|
|
|
ON_MESSAGE(WM_PROCESS, OnProcessInfo)
|
|
|
ON_MESSAGE(WM_SHOWREPEATINFO, OnShowRepeatInfo)
|
|
|
+ ON_MESSAGE(WM_SHOWCSVINFO, OnShowCvsInfo)
|
|
|
ON_BN_CLICKED(IDCANCEL, &CMFCApplication1Dlg::OnBnClickedCancel)
|
|
|
ON_BN_CLICKED(IDC_BTN_TXT, &CMFCApplication1Dlg::OnBnClickedBtnTxt)
|
|
|
ON_BN_CLICKED(IDC_BTN_PDF, &CMFCApplication1Dlg::OnBnClickedBtnPdf)
|
|
@@ -514,6 +516,9 @@ BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
|
|
|
ON_BN_CLICKED(ID_BTN_SCAN, &CMFCApplication1Dlg::OnBnClickedBtnScan)
|
|
|
ON_BN_CLICKED(IDC_BTN_REPEATPATH, &CMFCApplication1Dlg::OnBnClickedBtnRepeatpath)
|
|
|
ON_BN_CLICKED(ID_BTN_REPEAT, &CMFCApplication1Dlg::OnBnClickedBtnRepeat)
|
|
|
+ ON_BN_CLICKED(IDC_BTN_CSVPATH, &CMFCApplication1Dlg::OnBnClickedBtnCsvpath)
|
|
|
+ ON_BN_CLICKED(IDC_BTN_CSVFILEDIR, &CMFCApplication1Dlg::OnBnClickedBtnCsvfiledir)
|
|
|
+ ON_BN_CLICKED(ID_BTN_BAIDU_IDENTIFY, &CMFCApplication1Dlg::OnBnClickedBtnBaiduIdentify)
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
@@ -556,6 +561,11 @@ BOOL CMFCApplication1Dlg::OnInitDialog()
|
|
|
GetDlgItem(IDC_EDIT_IMGPATH)->SetWindowText(CConfig::Instance()->m_strImg);
|
|
|
GetDlgItem(IDC_EDIT_CUTPATH)->SetWindowText(CConfig::Instance()->m_strCut);
|
|
|
GetDlgItem(IDC_EDIT_REPEATPATH)->SetWindowText(CConfig::Instance()->m_strRepeat);
|
|
|
+ GetDlgItem(IDC_EDIT_CSVPATH)->SetWindowText(CConfig::Instance()->m_strCsvPath);
|
|
|
+ GetDlgItem(IDC_EDIT_CSVFILEDIR)->SetWindowText(CConfig::Instance()->m_strCsvFileDir);
|
|
|
+
|
|
|
+ GetDlgItem(IDC_STATIC_CSV_PROCESS)->SetWindowText(L"--/--");
|
|
|
+
|
|
|
|
|
|
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
|
|
|
}
|
|
@@ -727,6 +737,36 @@ LRESULT CMFCApplication1Dlg::OnShowRepeatInfo(WPARAM wParam, LPARAM lParam)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+LRESULT CMFCApplication1Dlg::OnShowCvsInfo(WPARAM wParam, LPARAM lParam)
|
|
|
+{
|
|
|
+ if (lParam == 1)
|
|
|
+ {
|
|
|
+ GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(TRUE);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ wchar_t* p = (wchar_t*)wParam;
|
|
|
+ CString str;
|
|
|
+ str.Format(_T("%s"), p);
|
|
|
+ if (lParam == 2)
|
|
|
+ {
|
|
|
+ CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CSV_PROCESS);
|
|
|
+ pStatic->SetWindowText(str);
|
|
|
+ return 0 ;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_strCsvMsg += str;
|
|
|
+ UpdateData(FALSE);
|
|
|
+
|
|
|
+ CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVMSG);
|
|
|
+ SCROLLINFO ScroInfo; // 定义SCROLLINFO 类型变量
|
|
|
+ pEdit->GetScrollInfo(SB_VERT, &ScroInfo); // 获取ScrollBar信息,其中m_recv为CEdit类型变量
|
|
|
+ pEdit->SetScrollPos(SB_VERT, ScroInfo.nMax); // 将滚动条设置为最大,即滚动到最底下;
|
|
|
+ pEdit->LineScroll(ScroInfo.nMax);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
LRESULT CMFCApplication1Dlg::OnProcessInfo(WPARAM wParam, LPARAM lParam)
|
|
|
{
|
|
|
CString strProcess = _T("--");
|
|
@@ -974,6 +1014,30 @@ void CMFCApplication1Dlg::FormatRepeatMsg(const char *szFmt, ...)
|
|
|
SendMessage(WM_SHOWREPEATINFO, (WPARAM)strMsg.GetBuffer(), 0);
|
|
|
}
|
|
|
|
|
|
+void CMFCApplication1Dlg::FormatCsvMsg(const char *szFmt, ...)
|
|
|
+{
|
|
|
+ if (!szFmt)
|
|
|
+ return;
|
|
|
+
|
|
|
+ va_list ap;
|
|
|
+ va_start(ap, szFmt);
|
|
|
+ size_t nLength = _vsnprintf(nullptr, 0, szFmt, ap) + 1;
|
|
|
+ CBuffers buffer;
|
|
|
+ char* szLogMsg = buffer.GetBuf(nLength);
|
|
|
+ _vsnprintf(szLogMsg, nLength, szFmt, ap);
|
|
|
+ va_end(ap);
|
|
|
+ SYSTEMTIME st;
|
|
|
+ GetLocalTime(&st);
|
|
|
+ char chBuf[24] = { 0 };
|
|
|
+ sprintf(chBuf, "%02d-%02d-%02d %02d:%02d:%02d ",
|
|
|
+ st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
|
|
+
|
|
|
+ CString strMsg;
|
|
|
+ // 扫描异常
|
|
|
+ strMsg.Format(L"%s %s\r\n", GB2312ToTstring(chBuf).c_str(), GB2312ToTstring(szLogMsg).c_str());
|
|
|
+ SendMessage(WM_SHOWCSVINFO, (WPARAM)strMsg.GetBuffer(), 0);
|
|
|
+}
|
|
|
+
|
|
|
HANDLE _threadRepeat = NULL;
|
|
|
|
|
|
|
|
@@ -1064,4 +1128,292 @@ void CMFCApplication1Dlg::OnBnClickedBtnRepeat()
|
|
|
|
|
|
SAFETY_EXIT_THREAD(_threadRepeat, 100);
|
|
|
_threadRepeat = CreateThread(NULL, 0, RepeatThread, NULL, 0, NULL);
|
|
|
-}
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void CMFCApplication1Dlg::SelectCsvFile(CString& lpszFile)
|
|
|
+{
|
|
|
+ CString OpenFilter = _T("文本文件(*.csv)|*.csv;|");
|
|
|
+ CFileDialog FileOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, OpenFilter);
|
|
|
+ if (IDOK == FileOpen.DoModal())
|
|
|
+ {
|
|
|
+ lpszFile = FileOpen.GetPathName();
|
|
|
+ lpszFile.Replace('\\', '/');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void CMFCApplication1Dlg::OnBnClickedBtnCsvpath()
|
|
|
+{
|
|
|
+ CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVPATH);
|
|
|
+ if (!pEdit)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ CString strText;
|
|
|
+ SelectCsvFile(strText);
|
|
|
+ if (strText.GetLength() == 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pEdit->SetWindowText(strText);
|
|
|
+ CConfig::Instance()->m_strCsvPath = strText;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void CMFCApplication1Dlg::OnBnClickedBtnCsvfiledir()
|
|
|
+{
|
|
|
+ CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVFILEDIR);
|
|
|
+ if (!pEdit)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ CString strText;
|
|
|
+ SelectFolder(GetSafeHwnd(), strText);
|
|
|
+ if (strText.GetLength() == 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pEdit->SetWindowText(strText);
|
|
|
+ CConfig::Instance()->m_strCsvFileDir = strText;
|
|
|
+}
|
|
|
+
|
|
|
+size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream)
|
|
|
+{
|
|
|
+ size_t written = fwrite(ptr, size, nmemb, stream);
|
|
|
+ printf("file writen byte:%zu\n", written);
|
|
|
+
|
|
|
+ return written;
|
|
|
+}
|
|
|
+
|
|
|
+int http_download(std::string url, std::string savepath)
|
|
|
+{
|
|
|
+ CURL* handle = nullptr;
|
|
|
+ FILE* fp;
|
|
|
+ CURLcode res;
|
|
|
+ handle = curl_easy_init();
|
|
|
+ if (handle)
|
|
|
+ {
|
|
|
+ fp = fopen(savepath.c_str(), "wb");
|
|
|
+ curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
|
|
|
+ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data);
|
|
|
+ curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
|
|
|
+ res = curl_easy_perform(handle);
|
|
|
+ fclose(fp);
|
|
|
+ curl_easy_cleanup(handle);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+* 手写文字识别
|
|
|
+* @return 调用成功返回0,发生错误返回其他错误码
|
|
|
+*/
|
|
|
+int handwriting_baidu_url(string img_url, std::string &json_result, const std::string &access_token)
|
|
|
+{
|
|
|
+ handwriting_result = "";
|
|
|
+ std::string url = request_url + "?access_token=" + access_token;
|
|
|
+ CURL *curl = NULL;
|
|
|
+ CURLcode result_code;
|
|
|
+ int is_success;
|
|
|
+ curl = curl_easy_init();
|
|
|
+ if (curl)
|
|
|
+ {
|
|
|
+ curl_easy_setopt(curl, CURLOPT_URL, url.data());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
|
+ curl_httppost *post = NULL;
|
|
|
+ curl_httppost *last = NULL;
|
|
|
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "url", CURLFORM_COPYCONTENTS, img_url.c_str(), CURLFORM_END);
|
|
|
+
|
|
|
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
|
|
|
+ result_code = curl_easy_perform(curl);
|
|
|
+ if (result_code != CURLE_OK)
|
|
|
+ {
|
|
|
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
|
|
+ curl_easy_strerror(result_code));
|
|
|
+ is_success = 1;
|
|
|
+ return is_success;
|
|
|
+ }
|
|
|
+ UTF8toANSI(handwriting_result);
|
|
|
+ json_result = handwriting_result;
|
|
|
+ curl_easy_cleanup(curl);
|
|
|
+ is_success = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fprintf(stderr, "curl_easy_init() failed.");
|
|
|
+ is_success = 1;
|
|
|
+ }
|
|
|
+ return is_success;
|
|
|
+}
|
|
|
+
|
|
|
+HANDLE _threadBdIdentify = NULL;
|
|
|
+DWORD WINAPI ThreadBdIdentify(void *param)
|
|
|
+{
|
|
|
+ CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd;
|
|
|
+
|
|
|
+ pWnd->FormatCsvMsg("启动百度切图线程......");
|
|
|
+ auto exitfun = [&]() {
|
|
|
+ pWnd->FormatCsvMsg("百度切图线程退出。");
|
|
|
+ SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, 0, 1);
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ std::ifstream csv_data(CConfig::Instance()->m_strCsvPath, std::ios::in);
|
|
|
+ std::string line;
|
|
|
+
|
|
|
+ if (!csv_data.is_open())
|
|
|
+ {
|
|
|
+ pWnd->FormatCsvMsg("打开CSV文件失败");
|
|
|
+ SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, 0, 1);
|
|
|
+ return 0L;
|
|
|
+ }
|
|
|
+
|
|
|
+ pWnd->FormatCsvMsg("开始解析CSV文件");
|
|
|
+ std::istringstream sin; //将整行字符串line读入到字符串istringstream中
|
|
|
+ std::vector<std::string> words; //声明一个字符串向量
|
|
|
+ std::string word;
|
|
|
+
|
|
|
+ std::list<std::tuple<std::string, std::string>> list_words;
|
|
|
+ // 读取标题行
|
|
|
+ std::getline(csv_data, line);
|
|
|
+ // 读取数据
|
|
|
+ while (std::getline(csv_data, line))
|
|
|
+ {
|
|
|
+ sin.clear();
|
|
|
+ sin.str(line);
|
|
|
+ words.clear();
|
|
|
+ while (std::getline(sin, word, ',')) //将字符串流sin中的字符读到field字符串中,以逗号为分隔符
|
|
|
+ {
|
|
|
+ words.push_back(word); //将每一格中的数据逐个push
|
|
|
+ }
|
|
|
+ if (words.size() >= 4)
|
|
|
+ {
|
|
|
+ list_words.push_back({ words[3],words[4] });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ csv_data.close();
|
|
|
+ pWnd->FormatCsvMsg("CSV文件解析结束");
|
|
|
+ pWnd->FormatCsvMsg("本次共【%d】条数据", list_words.size());
|
|
|
+
|
|
|
+ wchar_t tempPath[MAX_PATH];
|
|
|
+ DWORD dwSize = MAX_PATH;
|
|
|
+ GetTempPath(dwSize, tempPath);//获取临时文件夹路径
|
|
|
+
|
|
|
+ string strToken = CT2A(CConfig::Instance()->m_strToken);
|
|
|
+ std::map<std::string, int> map_count;
|
|
|
+ uint current_cnt = 1;
|
|
|
+ for (auto& iter : list_words)
|
|
|
+ {
|
|
|
+ std::string anser_url = std::get<0>(iter);
|
|
|
+ std::string anser_type = std::get<1>(iter);
|
|
|
+ std::wstring anser_type_w = CA2T(anser_type.c_str());
|
|
|
+ map_count[anser_type]++;
|
|
|
+
|
|
|
+ int group = map_count[anser_type] / 10000 + 1;
|
|
|
+ CString save_dir_type;
|
|
|
+ CString save_dir_type_group;
|
|
|
+ save_dir_type.Format(L"%s/%s", CConfig::Instance()->m_strCsvFileDir, anser_type_w.c_str());
|
|
|
+ save_dir_type_group.Format(L"%s/%s/%d", CConfig::Instance()->m_strCsvFileDir, anser_type_w.c_str(), group);
|
|
|
+
|
|
|
+ if (!PathIsDirectory(save_dir_type))
|
|
|
+ {
|
|
|
+ ::CreateDirectory(save_dir_type, 0);
|
|
|
+ }
|
|
|
+ if (!PathIsDirectory(save_dir_type_group))
|
|
|
+ {
|
|
|
+ ::CreateDirectory(save_dir_type_group, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string strResult;
|
|
|
+ vector<std::tuple<cv::Rect, std::string>> vecTranslate;
|
|
|
+ int trycnt = 3;
|
|
|
+ bool ret = false;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ handwriting_baidu_url(anser_url, strResult, strToken);
|
|
|
+ ret = ParseJson(strResult, vecTranslate);
|
|
|
+ if (ret)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ trycnt--;
|
|
|
+ } while (trycnt > 0);
|
|
|
+
|
|
|
+ if (!ret)
|
|
|
+ {
|
|
|
+ pWnd->FormatCsvMsg("调用百度接口,生成识别JSON失败");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ CString save_dir_src_img;
|
|
|
+ DWORD dwCount = GetTickCount();
|
|
|
+ time_t tt = std::time(0);
|
|
|
+ std::wstring guid = CA2T(GenerateGUID().c_str());
|
|
|
+ save_dir_src_img.Format(L"%s/%s/%s_%lld_%ld.jpg", CConfig::Instance()->m_strCsvFileDir, L"src_img", guid.c_str(), tt, dwCount);
|
|
|
+ std::string img_path = CT2A(save_dir_src_img.GetBuffer());
|
|
|
+
|
|
|
+ int ret_download = http_download(anser_url, img_path);
|
|
|
+ if (ret_download != CURLE_OK)
|
|
|
+ {
|
|
|
+ pWnd->FormatCsvMsg("下载失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string save_dir_type_group_a = CT2A(save_dir_type_group);
|
|
|
+ int ret_cut = cutPaper(img_path, save_dir_type_group_a, vecTranslate);
|
|
|
+ if (ret_cut == 0)
|
|
|
+ {
|
|
|
+ CString strInfo;
|
|
|
+ strInfo.Format(L"%d/%d", current_cnt, list_words.size());
|
|
|
+ SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, (WPARAM)strInfo.GetBuffer(), 2);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pWnd->FormatCsvMsg("生成第%d份数据失败", current_cnt);
|
|
|
+ }
|
|
|
+ current_cnt++;
|
|
|
+ }
|
|
|
+
|
|
|
+ exitfun();
|
|
|
+ return 0L;
|
|
|
+}
|
|
|
+
|
|
|
+void CMFCApplication1Dlg::OnBnClickedBtnBaiduIdentify()
|
|
|
+{
|
|
|
+ if (CConfig::Instance()->m_strCsvPath.GetLength() == 0)
|
|
|
+ {
|
|
|
+ AfxMessageBox(L"CSV文件路径未选择");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CConfig::Instance()->m_strCsvFileDir.GetLength() == 0)
|
|
|
+ {
|
|
|
+ AfxMessageBox(L"切图文件夹未选择");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(FALSE);
|
|
|
+ m_strCsvMsg = "";
|
|
|
+
|
|
|
+
|
|
|
+ CString src_img_dir(CConfig::Instance()->m_strCsvFileDir);
|
|
|
+ src_img_dir.Append(L"/src_img");
|
|
|
+ if (!PathIsDirectory(src_img_dir))
|
|
|
+ {
|
|
|
+ BOOL ret = ::CreateDirectory(src_img_dir, 0);
|
|
|
+ if (!ret)
|
|
|
+ {
|
|
|
+ GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(TRUE);
|
|
|
+ AfxMessageBox(L"源图文件夹路径创建失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SAFETY_EXIT_THREAD(_threadBdIdentify, 100);
|
|
|
+ _threadBdIdentify = CreateThread(NULL, 0, ThreadBdIdentify, NULL, 0, NULL);
|
|
|
+}
|