From 0c4229c3472b0f46ab82c5bbb15300b67f4a8da6 Mon Sep 17 00:00:00 2001 From: lovelyyoung <1002639516@qq.com> Date: Tue, 15 Nov 2022 11:55:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?2022=E5=B9=B410=E6=9C=8828=E6=97=A5=20?= =?UTF-8?q?=E5=BD=AD=E6=98=8E=20=09=E7=89=88=E6=9C=AC=E5=8F=B7=EF=BC=9A=20?= =?UTF-8?q?=091.=20=E7=89=88=E6=9C=AC=E5=A2=9E=E5=8A=A0HSV=E7=AD=94?= =?UTF-8?q?=E9=A2=98=E5=8D=A1=E7=95=99=E7=BA=A2=E9=99=A4=E6=9D=82=E8=89=B2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=A2=9E=E5=8A=A0Twain=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=EF=BC=880x8116=EF=BC=89=EF=BC=8C=E4=BB=A5=E5=8F=8AUI?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=8E=A7=E4=BB=B6=E4=BA=92=E6=96=A5=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=9B=20=092.=20GScanCap=E5=A2=9E=E5=8A=A0HSVFilte?= =?UTF-8?q?rType=E5=AD=97=E6=AE=B5=E5=AE=9A=E4=B9=89=EF=BC=9B=20=093.=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0PC=E6=9C=AC=E5=9C=B0=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E5=A4=84=E7=90=86=E7=AE=97=E6=B3=95=EF=BC=88HSV=E7=95=99?= =?UTF-8?q?=E7=BA=A2=E9=99=A4=E6=9D=82=E8=89=B2=20v1.4=20->v1.5.1=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=BA=A0=E5=81=8F=E8=A3=81=E5=88=87=E7=AE=97?= =?UTF-8?q?=E6=B3=95=20v1.3.12->v1.4.2=EF=BC=89=202022=E5=B9=B411=E6=9C=88?= =?UTF-8?q?6=E6=97=A5=20=091.=20=E9=92=88=E5=AF=B9G300=203288=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=20=E5=A2=9E=E5=8A=A0200=20300=E7=9C=9F=E5=AE=9EDPI?= =?UTF-8?q?=EF=BC=9B=20=092.=20=E5=BC=80=E6=94=BE=E9=80=9F=E5=BA=A6?= =?UTF-8?q?=E4=BC=98=E5=85=88=E4=BB=A5=E5=8F=8A=E7=94=BB=E8=B4=A8=E4=BC=98?= =?UTF-8?q?=E5=85=88=E6=A8=A1=E5=BC=8F=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.txt | 10 +- huagao/CImageProcPage.cpp | 22 +- huagao/CImageProcPage.h | 1 + huagao/CTwainUI.cpp | 14 +- huagao/Device/G400ScanConfig.cpp | 4 +- huagao/Device/GScan439Android.cpp | 2 +- huagao/Device/GScanO1003399.cpp | 3 +- huagao/Device/GScanO400.cpp | 39 +- huagao/Device/ImageMatQueue.cpp | 21 +- huagao/Device/PublicFunc.h | 8 +- huagao/Device/scn_config.cpp | 2 +- huagao/GscanJsonConfig.cpp | 4 + huagao/ImageProcess/ImageApplyAutoCrop.cpp | 541 +++++++++---------- huagao/ImageProcess/ImageApplyAutoCrop.h | 80 +-- huagao/ImageProcess/ImageApplyHSVCorrect.cpp | 227 ++++---- huagao/ImageProcess/ImageApplyHSVCorrect.h | 29 +- huagao/huagaods.cpp | 18 + huagao/huagaotwds.rc | Bin 54578 -> 53444 bytes huagao/resource.h | Bin 21084 -> 21268 bytes huagao/stdafx.h | Bin 25538 -> 25538 bytes 20 files changed, 547 insertions(+), 478 deletions(-) diff --git a/changelog.txt b/changelog.txt index c32d18d3..8f0df60f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -64,4 +64,12 @@ 2.屏蔽3288 自适应幅面功能 3.修复显示UI时通过协议reset停止扫描时按钮未正常复位问题 4.更新除穿孔以及跳过空白页算法 - 5.新增待纸扫描超时设置 -- 22.10.20 \ No newline at end of file + 5.新增待纸扫描超时设置 -- 22.10.20 +2022年10月28日 彭明 + 版本号: + 1. 版本增加HSV答题卡留红除杂色功能,增加Twain协议(0x8116),以及UI部分控件互斥逻辑; + 2. GScanCap增加HSVFilterType字段定义; + 3. 更新PC本地图像处理算法(HSV留红除杂色 v1.4 ->v1.5.1 自动纠偏裁切算法 v1.3.12->v1.4.2) +2022年11月6日 + 1. 针对G300 3288 版本 增加200 300真实DPI; + 2. 开放速度优先以及画质优先模式; \ No newline at end of file diff --git a/huagao/CImageProcPage.cpp b/huagao/CImageProcPage.cpp index bb238060..466a336f 100644 --- a/huagao/CImageProcPage.cpp +++ b/huagao/CImageProcPage.cpp @@ -45,6 +45,7 @@ CImageProcPage::CImageProcPage(CWnd* pParent /*=nullptr*/) , m_ckbRemoveHole(FALSE) , m_ckbDetachNoise(FALSE) , m_ckbHSVCorrect(FALSE) + , m_ckbHSVDetechNoise(FALSE) , indent(5) , noise(8) ,threshold(40) @@ -77,7 +78,8 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool if (val == 0) { GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(TRUE); - GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(TRUE); + //GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(TRUE); + GetDlgItem(IDC_CKB_ANSWERSHEETFILTER)->EnableWindow(TRUE); if (dpi >= 500) { GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(FALSE); ((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE); @@ -94,8 +96,13 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool else { GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(FALSE); ((CButton*)GetDlgItem(IDC_CKHSVCORRECT))->SetCheck(FALSE); - GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); - ((CButton*)GetDlgItem(IDC_CKBACKGROUNDSMOOTH))->SetCheck(FALSE); + //GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); + //((CButton*)GetDlgItem(IDC_CKBACKGROUNDSMOOTH))->SetCheck(FALSE); + + GetDlgItem(IDC_CKB_ANSWERSHEETFILTER)->EnableWindow(FALSE); + ((CButton*)GetDlgItem(IDC_CKB_ANSWERSHEETFILTER))->SetCheck(FALSE); + ((CButton*)GetDlgItem(IDC_CKB_ANSWERSHEETFILTER))->SetCheck(FALSE); + GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(FALSE); ((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE); GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE); @@ -112,14 +119,14 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool else { m_temp->EnableWindow(TRUE); - GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); + //GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); } - if (val == 2) + if (val == 2)//黑白模式下 { ((CButton*)GetDlgItem(IDC_CHECKDETACHNOISE))->EnableWindow(true); - //m_temp->SetCurSel(4); + GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); } else { @@ -140,6 +147,8 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool else ((CButton*)GetDlgItem(IDC_CKCROPMODEL))->EnableWindow(true); + //GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(val<=1?TRUE:FALSE); + } void CImageProcPage::ImageAutoDescrewUpdate(int val) @@ -170,6 +179,7 @@ void CImageProcPage::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_CKREMOVEHOLE, m_ckbRemoveHole); DDX_Check(pDX, IDC_CHECKDETACHNOISE,m_ckbDetachNoise); DDX_Check(pDX, IDC_CKHSVCORRECT, m_ckbHSVCorrect); + DDX_Check(pDX, IDC_CKB_ANSWERSHEETFILTER, m_ckbHSVDetechNoise); } BOOL CImageProcPage::OnInitDialog() diff --git a/huagao/CImageProcPage.h b/huagao/CImageProcPage.h index ba3b851c..3a3c2475 100644 --- a/huagao/CImageProcPage.h +++ b/huagao/CImageProcPage.h @@ -29,6 +29,7 @@ public: BOOL m_ckbMultioutput; BOOL m_ckbRemoveHole; BOOL m_ckbHSVCorrect; + BOOL m_ckbHSVDetechNoise; BOOL m_ckbDetachNoise; void ImageProcPageUpdate(int val,int twss,int cmduplexsel, bool is_Crop,int dpi); void ImageAutoDescrewUpdate(int val); diff --git a/huagao/CTwainUI.cpp b/huagao/CTwainUI.cpp index 71a44572..c891bc67 100644 --- a/huagao/CTwainUI.cpp +++ b/huagao/CTwainUI.cpp @@ -144,7 +144,13 @@ BOOL CTwainUI::OnInitDialog() ((CButton*)m_pageBasic->GetDlgItem(IDC_RDQUALITYPRIORITY))->ShowWindow(SW_SHOW); ((CButton*)m_pageBasic->GetDlgItem(IDC_RDSPEEDPRIORITY))->ShowWindow(SW_SHOW); } -#endif // G400 +#elif defined(G300) + if (atoi(m_hardwareVersion.substr(4, 6).c_str()) >= 221106) + { + ((CButton*)m_pageBasic->GetDlgItem(IDC_RDQUALITYPRIORITY))->ShowWindow(SW_SHOW); + ((CButton*)m_pageBasic->GetDlgItem(IDC_RDSPEEDPRIORITY))->ShowWindow(SW_SHOW); + } +#endif setvisable_dogear(false); setvisable_autopaper(false); setvisable_fixedpaper(false); @@ -294,6 +300,7 @@ void CTwainUI::UpdateUI() m_pageImageProc->m_en_fillhole_right = settings->en_fillholeratio_right; m_pageImageProc->GetDlgItem(IDC_SLDOUTHOLE)->EnableWindow(m_pageImageProc->m_ckbRemoveHole); m_pageImageProc->m_ckbfadeback = settings->fadeback; + m_pageImageProc->m_ckbHSVDetechNoise = settings->hsvFilter; ((CButton*)m_pageImageProc->GetDlgItem(IDC_CKBACKGROUNDSMOOTH))->SetCheck(m_pageImageProc->m_ckbfadeback); ((CButton*)m_pageImageProc->GetDlgItem(IDC_CKBACKGROUNDSMOOTH))->EnableWindow(settings->pixtype == 2); m_pageImageProc->m_edit_faderange.SetValue(settings->fadeback_range); @@ -315,7 +322,10 @@ void CTwainUI::UpdateUI() m_pageImageProc->m_ckbMultioutput = settings->multi_output_red == TRUE ? TRUE : FALSE;//多流除红 else m_pageImageProc->m_ckbMultioutput = FALSE;//多流除红 + m_pageImageProc->m_ckbHSVCorrect = settings->hsvcorrect == TRUE ? TRUE : FALSE;//答题卡除红 + m_pageImageProc->m_ckbHSVDetechNoise = settings->hsvFilter == TRUE ? TRUE : FALSE; + m_pageImageProc->GetDlgItem(IDC_CKMULTIOUTPUT)->EnableWindow(settings->pixtype == 2);//彩色可用 ((CButton*)m_pageImageProc->GetDlgItem(IDC_CKMULTIOUTPUT))->SetCheck(settings->pixtype == 2); m_pageImageProc->UpdateData(FALSE); @@ -566,6 +576,7 @@ void CTwainUI::UpDateScanParam(PCONFIGPARAMS configItem, bool updateDs) configItem->EnMultiOutPutR = m_pageImageProc->m_ckbMultioutput;//多流除红 configItem->EnHsvCorrect = m_pageImageProc->m_ckbHSVCorrect;//答题卡除红 + configItem->EnHsvFilterDetechNoise = m_pageImageProc->m_ckbHSVDetechNoise; //!< Page feed paper m_pageFeedPaper->UpdateData(); @@ -690,6 +701,7 @@ void CTwainUI::UpDateScanParam(PCONFIGPARAMS configItem, bool updateDs) settings->en_multi_output = ((CButton*)m_pageImageProc->GetDlgItem(IDC_CHMULTIPUT))->GetCheck(); settings->multioutput = ((CComboBox*)m_pageImageProc->GetDlgItem(IDC_CMBMULTIOUT))->GetCurSel(); settings->hsvcorrect = configItem->EnHsvCorrect; + settings->hsvFilter = configItem->EnHsvFilterDetechNoise; #ifdef REAL300DPI settings->resolution_native = settings->resolution_dst > 240.0f ? 300.0f : 200.0f; #else // REAL300DPI diff --git a/huagao/Device/G400ScanConfig.cpp b/huagao/Device/G400ScanConfig.cpp index a84c5437..446721f0 100644 --- a/huagao/Device/G400ScanConfig.cpp +++ b/huagao/Device/G400ScanConfig.cpp @@ -6,7 +6,7 @@ G400ScanConfig::G400ScanConfig(GScanCap& gcap) cfg.params.doubleFeeded = gcap.hardwarecaps.en_doublefeed == 0 ? 0 : 1; cfg.params.dpi = G400_DPI::G400_D200;//gcap.resolution_dst <= 200.0f ? G400_DPI::G400_D200 : (gcap.resolution_dst <= 300.0f ? G400_DPI::G400_D300 : G400_DPI::G400_D600); cfg.params.enableLed = 1; - if (gcap.filter != 3 || gcap.enhance_color) + if (gcap.filter != 3 || gcap.enhance_color||gcap.hsvFilter!=0||gcap.hsvcorrect!=0||gcap.fadeback!=0) cfg.params.isColor = 1; else cfg.params.isColor = SupPixelTypes[gcap.pixtype]; @@ -46,7 +46,7 @@ G400AndroidScanConfig::G400AndroidScanConfig(GScanCap& gcap) cfg.params.doubleFeeded = gcap.hardwarecaps.en_doublefeed == 0 ? 0 : 1; cfg.params.dpi = G400_DPI::G400_D200;//gcap.resolution_dst <= 200.0f ? G400_DPI::G400_D200 : (gcap.resolution_dst <= 300.0f ? G400_DPI::G400_D300 : G400_DPI::G400_D600); cfg.params.enableLed = 1; - if (gcap.filter != 3 || gcap.enhance_color) + if (gcap.filter != 3 || gcap.enhance_color ||gcap.fadeback!=0|| gcap.hsvFilter != 0) cfg.params.isColor = 1; else cfg.params.isColor = SupPixelTypes[gcap.pixtype]; diff --git a/huagao/Device/GScan439Android.cpp b/huagao/Device/GScan439Android.cpp index 37ff72ba..cacb1846 100644 --- a/huagao/Device/GScan439Android.cpp +++ b/huagao/Device/GScan439Android.cpp @@ -202,7 +202,7 @@ void GScan439Android::config_params(GScanCap& param) PaperStatus ps = { param.papertype,param.paperAlign }; cfg.g200params.paper = SupPaperTyps.count(ps) > 0 ? SupPaperTyps[ps] : 0; - if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect) + if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect||param.hsvFilter!=0||param.fadeback!=0) cfg.g200params.color = 1;//color else { diff --git a/huagao/Device/GScanO1003399.cpp b/huagao/Device/GScanO1003399.cpp index 42f33ca3..09055117 100644 --- a/huagao/Device/GScanO1003399.cpp +++ b/huagao/Device/GScanO1003399.cpp @@ -279,7 +279,7 @@ void GScanO1003399::config_params(GScanCap& param) // cfg.g200params.paper = SupPaperTyps_39.count(ps) > 0 ? SupPaperTyps_39[ps] : 0; //} - if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect) + if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect||param.hsvFilter!=0||param.fadeback!=0) cfg.g200params.color = 1;//color else { @@ -326,6 +326,7 @@ void GScanO1003399::config_params(GScanCap& param) param39.gamma = param.gamma; param39.hardwarecaps = param.hardwarecaps; param39.hsvcorrect = param.hsvcorrect; + param39.HsvFilterType = param.hsvFilter; param39.imageRotateDegree = param.imageRotateDegree; param39.indent = param.indent; param39.is_autocontrast = param.is_autocontrast; diff --git a/huagao/Device/GScanO400.cpp b/huagao/Device/GScanO400.cpp index f0da883d..e15a5739 100644 --- a/huagao/Device/GScanO400.cpp +++ b/huagao/Device/GScanO400.cpp @@ -412,8 +412,45 @@ void GScanO400::config_params(GScanCap& params) } } else -#endif // G400 params.resolution_native = 200.0f; +#elif defined(G300) + if (atoi(fw.substr(4, 6).c_str()) >= 221106) + { + int dpi = 1; + if (params.is_high_imagequality) + { + if (params.resolution_dst < 300) { + params.resolution_native = 200.0f; + dpi = 1; + } + else if (params.resolution_dst >= 300 && params.resolution_dst < 500) { + params.resolution_native = 300.0f; + dpi = 2; + } + else { + params.resolution_native = 600.0f; + dpi = 3; + } + cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); + } + else + { + if (params.resolution_dst < 500) + { + params.resolution_native = 200.0f; + dpi = 1; + } + else + { + params.resolution_native = 300.0f; + dpi = 2; + } + cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); + } + } + else + params.resolution_native = 200.0f; +#endif //G300 gcap = params; USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; FileTools::writelog(log_INFO, "config hardware param" + to_string(cfgdata)); diff --git a/huagao/Device/ImageMatQueue.cpp b/huagao/Device/ImageMatQueue.cpp index 7a8e3988..e97a6b87 100644 --- a/huagao/Device/ImageMatQueue.cpp +++ b/huagao/Device/ImageMatQueue.cpp @@ -190,7 +190,7 @@ void ImageMatQueue::setparam(const GScanCap& param) #endif bool normalCrop = ((param.autodescrew) || (islongcustomcrop ? islongcustomcrop : param.is_autocrop) || (param.fillbackground)) ? false : param.normalCrop; m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, - param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent, normalCrop))); + param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent, normalCrop,param.hsvFilter==0))); /* m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(true, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent))); if(!(islongcustomcrop ? islongcustomcrop : param.is_autocrop)) @@ -202,7 +202,8 @@ void ImageMatQueue::setparam(const GScanCap& param) // m_iaList.push_back(shared_ptr(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::LowSaturation_Removal, true))); //} - if (param.fadeback && param.pixtype == 2) { + if (param.fadeback)//&& param.pixtype == 2 + { m_iaList.push_back(shared_ptr(new CImageApplyFadeBackGroudColor(100,0,param.fadeback_range))); } //filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b @@ -225,9 +226,15 @@ void ImageMatQueue::setparam(const GScanCap& param) } //答题卡除红 - if (scanParam.hsvcorrect) + if ((scanParam.hsvcorrect || scanParam.hsvFilter)&&scanParam.pixtype==2) { - m_iaList.push_back(shared_ptr(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::Red_Removal))); + CImageApplyHSVCorrect::CorrectOption hsv;//= config.hsvcorrect?CImageApplyHSVCorrect::CorrectOption::Red_Removal: + if (scanParam.hsvcorrect) + hsv = CImageApplyHSVCorrect::CorrectOption::Red_Removal; + else + hsv = CImageApplyHSVCorrect::CorrectOption::FXB_Colour_Cast; + + m_iaList.push_back(shared_ptr(new CImageApplyHSVCorrect(hsv))); } //锐化 if (param.sharpen) { @@ -723,7 +730,7 @@ void ImageMatQueue::duplex_process(CacheInfo info) CImageApply* ptr = m_iaList[j].get(); if (typeid(*ptr) == typeid(CImageApplyAutoCrop)) { - rects = dynamic_cast(ptr)->rotatedROIs(); + //rects = dynamic_cast(ptr)->rotatedROIs(); isDesaskew = dynamic_cast(ptr)->isDesaskew(); } else if (typeid(*ptr) == typeid(CImageApplyRotation)) @@ -766,7 +773,7 @@ void ImageMatQueue::duplex_process(CacheInfo info) if (scanParam.pixtype == 1 && mats[i].channels() == 3)//gray cv::cvtColor(mats[i], mats[i], COLOR_BGR2GRAY); #else - if (scanParam.pixtype == 1 && scanParam.hsvcorrect) + if (scanParam.pixtype == 1 && (scanParam.hsvcorrect || scanParam.fadeback))// && scanParam.hsvcorrect if (mats[i].channels() == 3) cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY); #endif @@ -837,7 +844,7 @@ void ImageMatQueue::single_process(cv::Mat& mat) for (int i = 0; i < mats.size(); i++) { if (!mats[i].empty()) { IMat2Bmp idata; - if (scanParam.pixtype == 1 && scanParam.hsvcorrect) + if (scanParam.pixtype == 1 && (scanParam.hsvcorrect!=0 || scanParam.fadeback)) if (mats[i].channels() == 3) cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY); if (scanParam.en_multi_output) { diff --git a/huagao/Device/PublicFunc.h b/huagao/Device/PublicFunc.h index 0846e6b9..f38765cb 100644 --- a/huagao/Device/PublicFunc.h +++ b/huagao/Device/PublicFunc.h @@ -101,7 +101,7 @@ const std::string INDENT = "Indent"; const std::string AUTOCROP_THRESHOLD = "AutoCrop_Threshold"; const std::string NOISE = "Noise"; const std::string LOWPOWERMODE = "ilowpowermode"; - +const std::string ANSWERSHEETFILTER = "iAnswersheetFilter"; //twain õȲ const std::string ROLLERMSGDATE = "RollerMsgDate"; @@ -145,6 +145,7 @@ typedef struct tagCONFIGPARAMS int OutHoleRatio; bool EnMultiOutPutR; bool EnHsvCorrect; + bool EnHsvFilterDetechNoise; /*ֽѡ*/ bool EnUltrasonicDetect; @@ -300,6 +301,7 @@ struct GScanCap bool en_fillholeratio_left; bool en_fillholeratio_right; int autopaper_timeout; + int hsvFilter; std::string Caption; std::string SavePath; }; @@ -382,7 +384,9 @@ struct GScanCap_3399 int fillholeratio_down; int fillholeratio_left; int fillholeratio_right; - uint32_t reserve[1024]; /**< Ԥ4096ֽЭչ*/ + std::uint8_t fold_concatmode; /*ƴģʽ*/ + int HsvFilterType; /**< ⿨ɫ ݶ0 Ϊرգ1Ϊɫ>*/ + uint32_t reserve[1023]; /**< Ԥ4096ֽЭչ*/ }; typedef struct Paper_Status { diff --git a/huagao/Device/scn_config.cpp b/huagao/Device/scn_config.cpp index 6370f0ca..e87dc82a 100644 --- a/huagao/Device/scn_config.cpp +++ b/huagao/Device/scn_config.cpp @@ -7,7 +7,7 @@ hgConfigClass::hgConfigClass(GScanCap param) m_param = { 0 }; PaperStatus ps = { param.papertype,param.paperAlign }; m_param.paper = ContainspaperTypesKey(ps) ? SupPaperTyps[ps] : 0; - if(param.filter!=3||param.enhance_color!=0||param.hsvcorrect) + if(param.filter!=3||param.enhance_color!=0||param.hsvcorrect|| param.fadeback != 0 || param.hsvFilter != 0) m_param.color = 1;//color else { diff --git a/huagao/GscanJsonConfig.cpp b/huagao/GscanJsonConfig.cpp index 5afb1cb0..cd3bf804 100644 --- a/huagao/GscanJsonConfig.cpp +++ b/huagao/GscanJsonConfig.cpp @@ -945,6 +945,7 @@ json GscanJsonConfig::GscancapToJson(GScanCap& cap) js[CONFIG][ITEMCAPTION] = cap.Caption; js[CONFIG][SAVEPATH] = cap.SavePath.c_str(); js[CONFIG][LOWPOWERMODE] = cap.hardwarecaps.lowpowermode; + js[CONFIG][ANSWERSHEETFILTER] = cap.hsvFilter; return js; } @@ -1019,6 +1020,7 @@ GScanCap GscanJsonConfig::JsonToGscancap(json& js) cap.indent = json_cast(js[CONFIG][INDENT]).to_int(); cap.AutoCrop_threshold = json_cast(js[CONFIG][AUTOCROP_THRESHOLD]).to_int(); cap.hardwarecaps.lowpowermode = (LowPowerMode)json_cast(js[CONFIG][LOWPOWERMODE]).to_int(); + cap.hsvFilter = json_cast(js[CONFIG][ANSWERSHEETFILTER]).to_int(); cap.is_convex = json_cast(js[CONFIG][ISCONVEX]).to_int(); cap.Caption = json_cast(js[CONFIG][ITEMCAPTION]).to_string(); cap.SavePath = json_cast(js[CONFIG][SAVEPATH]).to_string(); @@ -1092,6 +1094,7 @@ json GscanJsonConfig::GetDefaultJson() "AutoCrop_Threshold": 40 , "isConvex": true , "ilowpowermode": 4, + "iAnswersheetFilter": 0, "Caption": "" , "SavePath": "" } @@ -1161,6 +1164,7 @@ json GscanJsonConfig::GetDefaultJson() "AutoCrop_Threshold": 40 , "isConvex": true , "ilowpowermode": 4, + "iAnswersheetFilter": 0, "Caption": "" , "SavePath": "" } diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.cpp b/huagao/ImageProcess/ImageApplyAutoCrop.cpp index 046625cd..923f9128 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.cpp +++ b/huagao/ImageProcess/ImageApplyAutoCrop.cpp @@ -1,5 +1,8 @@ #include "ImageApplyAutoCrop.h" #include "ImageProcess_Public.h" +#include +#include +#include "ImageApplyDispersion.h" CImageApplyAutoCrop::CImageApplyAutoCrop() : m_isCrop(false) @@ -11,11 +14,12 @@ CImageApplyAutoCrop::CImageApplyAutoCrop() , m_noise(8) , m_indent(5) , m_normalCrop(false) + , m_isDispersion(true) { } CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor, - double threshold, int noise, int indent, bool normalCrop) + double threshold, int noise, int indent, bool normalCrop, bool dispersion) : m_isCrop(isCrop) , m_isDesaskew(isDesaskew) , m_isFillBlank(isFillBlank) @@ -26,6 +30,7 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi , m_indent(indent) , m_fixedSize(fixedSize) , m_normalCrop(normalCrop) + , m_isDispersion(dispersion) { } @@ -33,313 +38,63 @@ CImageApplyAutoCrop::~CImageApplyAutoCrop() { } -cv::Mat concatenateMatrix(const cv::Mat& first, const cv::Mat& second) -{ - cv::Mat mul1 = cv::Mat::eye(3, 3, CV_64F); - cv::Mat mul2 = cv::Mat::eye(3, 3, CV_64F); - cv::Mat mul_r; - first.convertTo(mul_r, CV_64F); - mul_r.row(0).copyTo(mul1.row(0)); - mul_r.row(1).copyTo(mul1.row(1)); - - second.convertTo(mul_r, CV_64F); - mul_r.row(0).copyTo(mul2.row(0)); - mul_r.row(1).copyTo(mul2.row(1)); - - mul1 = mul2 * mul1; - mul_r = first.clone(); - mul1.row(0).copyTo(mul_r.row(0)); - mul1.row(1).copyTo(mul_r.row(1)); - return mul_r; -} - -std::vector comMat() -{ - std::vector mats; - cv::Point2f srcTri[3]; - srcTri[0] = cv::Point2f(1, 1); - srcTri[1] = cv::Point2f(1, 0); - srcTri[2] = cv::Point2f(0, 1); - const float fact = 0.33f; - float pos[] = { 0, 2 * fact, fact }; - cv::Point2f dstTri[3]; - for (int i = 0; i < 3; i++) - { - dstTri[0] = cv::Point2f(1, 1 + pos[i]); - dstTri[1] = cv::Point2f(1, pos[i]); - dstTri[2] = cv::Point2f(0, 1 + pos[i]); - - mats.push_back(cv::getAffineTransform(srcTri, dstTri)); - } - return mats; -} - -void brightSharp(cv::Mat& src) -{ - const float a = -0.49f; - const float b = 3.0f; - //float kernel_data[] = { - // a, 0, 0, 0, a, - // 0, 0, a, 0, 0, - // 0, a, b, a, 0, - // 0, 0, a, 0, 0, - // a, 0, 0, 0, a }; - - float kernel_data[] = { - 0, a, 0, - a, b, a, - 0, a, 0 - }; - cv::Mat kernel(3, 3, CV_32FC1, kernel_data); - cv::filter2D(src, src, src.depth(), kernel); -} - void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) { - (void)side; - if (pDib.empty()) return; - - if (m_normalCrop) - { - cv::Rect roi = cv::Rect((pDib.cols - m_fixedSize.width) / 2, side == 0 ? 75 : 145, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows); - pDib = pDib(roi).clone(); - m_rect = cv::RotatedRect(cv::Point2f(roi.x + roi.width / 2, roi.y + roi.height / 2), cv::Size2f(roi.width, roi.height), 0.0f); - return; - } - - if (!m_isCrop && !m_isDesaskew && !m_isFillBlank && m_fixedSize.empty()) return; - - cv::Mat src = pDib; - cv::Mat thre; cv::Mat dst; - hg::threshold_Mat(src, thre, m_threshold); - - if (m_noise > 0) - { - cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise, 1)); - cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); - } - - if (m_indent > 0) - { - cv::Mat element = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(m_indent, m_indent)); - cv::morphologyEx(thre, thre, cv::MORPH_ERODE, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); - } - - std::vector hierarchy; - std::vector> contours; - - hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); - m_maxContour = hg::getMaxContour(contours, hierarchy); - - if (m_maxContour.size() == 0) - { - thre.release(); - // - if (!m_isCrop) - pDib = pDib(cv::Rect((pDib.cols - m_fixedSize.width) / 2, (pDib.rows - m_fixedSize.height) / 2, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows)).clone(); -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply"); -#endif // LOG - return; - } - - thre.release(); - dst.release(); - - cv::RotatedRect rect = hg::getBoundingRect(m_maxContour); - m_rect = rect; - cv::Rect boudingRect = cv::boundingRect(m_maxContour); - boudingRect.x -= 1; - boudingRect.y -= 1; - boudingRect.width += 2; - boudingRect.height += 2; - - if (m_isDesaskew && rect.angle != 0) - { - cv::Point2f srcTri[4], srcTri_temp[3], dstTri[3]; - rect.points(srcTri); - - dstTri[0] = cv::Point2f(0, rect.size.height - 1); - dstTri[1] = cv::Point2f(0, 0); - dstTri[2] = cv::Point2f(rect.size.width - 1, 0); - - srcTri_temp[0] = dstTri[0]; - srcTri_temp[1] = dstTri[1]; - srcTri_temp[2] = dstTri[2]; - cv::Mat warp_mat; - warp_mat = cv::getAffineTransform(srcTri, dstTri); - if (src.channels() == 1) - { - cv::warpAffine(src, dst, warp_mat, rect.size, cv::INTER_LINEAR); - } - else - { - cv::Mat bgr[3]; - cv::split(src, bgr); - auto mats = comMat(); - warp_mat = cv::getAffineTransform(srcTri, dstTri); - warp_mat = concatenateMatrix(mats[0], warp_mat); - - cv::warpAffine(bgr[0], bgr[0], warp_mat, rect.size, cv::INTER_LINEAR); - - warp_mat = cv::getAffineTransform(srcTri, dstTri); - warp_mat = concatenateMatrix(mats[1], warp_mat); - cv::warpAffine(bgr[1], bgr[1], warp_mat, rect.size, cv::INTER_LINEAR); - - warp_mat = cv::getAffineTransform(srcTri, dstTri); - warp_mat = concatenateMatrix(mats[2], warp_mat); - cv::warpAffine(bgr[2], bgr[2], warp_mat, rect.size, cv::INTER_LINEAR); - - cv::merge(bgr, 3, dst); - } - - double* ptr_m = reinterpret_cast(warp_mat.data); - double a = ptr_m[0]; - double b = ptr_m[1]; - double c = ptr_m[2]; - double d = ptr_m[3]; - double e = ptr_m[4]; - double f = ptr_m[5]; - - for (cv::Point& p : m_maxContour) - { - p.x = static_cast(a * p.x + b * p.y + c); - p.y = static_cast(d * p.x + e * p.y + f); - } - - for (std::vector& sub : contours) - for (cv::Point& p : sub) - { - p.x = static_cast(a * p.x + b * p.y + c); - p.y = static_cast(d * p.x + e * p.y + f); - } - } - else - { - auto t_rect = boudingRect & cv::Rect(0, 0, src.cols, src.rows); - dst = src(t_rect); - if (dst.channels() == 3) - { - cv::Mat bgr[3]; - cv::split(dst, bgr); - auto mats = comMat(); - for (int i = 0; i < 3; i++) - cv::warpAffine(bgr[i], bgr[i], mats[i], t_rect.size(), cv::INTER_LINEAR); - cv::merge(bgr, 3, dst); - } - - m_maxContour.clear(); - m_maxContour.push_back(cv::Point(0, t_rect.height - 1)); - m_maxContour.push_back(cv::Point(0, 0)); - m_maxContour.push_back(cv::Point(t_rect.width - 1, 0)); - m_maxContour.push_back(cv::Point(t_rect.width - 1, t_rect.height - 1)); - - contours.clear(); - contours.push_back(m_maxContour); - } - - cv::Scalar autoBGColor; - if (m_isFillBlank) - { - if (m_isConvexHull) - { - if (m_maxContour.size() == 0) - { - thre.release(); - - if (!m_isCrop) - pDib = pDib(cv::Rect((pDib.cols - m_fixedSize.width) / 2, (pDib.rows - m_fixedSize.height) / 2, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows)).clone(); - return; - } - hg::convexHull(m_maxContour, m_maxContour); - contours.clear(); - contours.push_back(m_maxContour); - } - - contours.push_back(std::vector()); - contours[contours.size() - 1].push_back(cv::Point(-1, dst.rows - 1)); - contours[contours.size() - 1].push_back(cv::Point(-1, -1)); - contours[contours.size() - 1].push_back(cv::Point(dst.cols, -1)); - contours[contours.size() - 1].push_back(cv::Point(dst.cols, dst.rows)); - - autoBGColor = m_isFillColor ? getBackGroudColor(pDib, rect.size.area()) : cv::Scalar(255, 255, 255); - hg::fillPolys(dst, contours, autoBGColor); - } - else - { - m_maxContour.clear(); - m_maxContour.push_back(cv::Point(-1, dst.rows)); - m_maxContour.push_back(cv::Point(-1, -1)); - m_maxContour.push_back(cv::Point(dst.cols, -1)); - m_maxContour.push_back(cv::Point(dst.cols, dst.rows)); - } - - pDib.release(); - if (/*(m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0)*/ m_isCrop) - pDib = dst.clone(); - else - { - pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? autoBGColor : cv::Scalar(0, 0, 0)); - - cv::Rect roi; - roi.x = dst.cols > pDib.cols ? (dst.cols - pDib.cols) / 2 : 0; - roi.width = cv::min(pDib.cols, dst.cols); - roi.y = dst.rows > pDib.rows ? (dst.rows - pDib.rows) / 2 : 0; - roi.height = cv::min(pDib.rows, dst.rows); - cv::Rect rect((pDib.cols - roi.width) / 2, (pDib.rows - roi.height) / 2, roi.width, roi.height); - - for (cv::Point& p : m_maxContour) - p += roi.tl(); - dst(roi).copyTo(pDib(rect)); - } -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8"); -#endif // LOG + autoCrop_desaskew_fillBlank(pDib, dst, m_isCrop, m_isDesaskew, m_isFillBlank, m_fixedSize.width, m_fixedSize.height, + m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_isDispersion); + pDib = dst; } void CImageApplyAutoCrop::apply(std::vector& mats, bool isTwoSide) { - if (mats.empty()) return; - if (!mats[0].empty()) { - apply(mats[0], 0); - m_rects.push_back(m_rect); - brightSharp(mats[0]); - } - - if (isTwoSide && mats.size() > 1) - { - cv::Size dSize = m_fixedSize; - if (!mats[0].empty()) - m_fixedSize = mats[0].size(); - if (!mats[1].empty()) { - apply(mats[1], 1); - m_rects.push_back(m_rect); - brightSharp(mats[1]); - } - - if (!mats[0].empty()) - m_fixedSize = dSize; + (void)isTwoSide; + int i = 0; + for (cv::Mat& var : mats) { + if (i != 0 && isTwoSide == false) + break; + if (!var.empty()) + apply(var, 0); + i++; } } -cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int total) +#define FRONT_TOP 70 +#define FX_FY 0.5f + +void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue) { - if (image.channels() == 3) - { - cv::Mat image_bgr[3]; - cv::split(image, image_bgr); + int interpolation = flags; + cv::Mat src = _src.getMat(), M0 = _M0.getMat(); + cv::Mat dst = _dst.getMat(); - uchar bgr[3]; - for (size_t i = 0; i < 3; i++) - bgr[i] = getBackGroudChannelMean(image_bgr[i], total); - return cv::Scalar(bgr[0], bgr[1], bgr[2]); + if (dst.data == src.data) + src = src.clone(); + + double M[6] = { 0 }; + cv::Mat matM(2, 3, CV_64F, M); + if (interpolation == cv::INTER_AREA) + interpolation = cv::INTER_LINEAR; + + M0.convertTo(matM, matM.type()); + + if (!(flags & cv::WARP_INVERSE_MAP)) + { + double D = M[0] * M[4] - M[1] * M[3]; + D = D != 0 ? 1. / D : 0; + double A11 = M[4] * D, A22 = M[0] * D; + M[0] = A11; M[1] *= -D; + M[3] *= -D; M[4] = A22; + double b1 = -M[0] * M[2] - M[1] * M[5]; + double b2 = -M[3] * M[2] - M[4] * M[5]; + M[2] = b1; M[5] = b2; } - else - return cv::Scalar::all(getBackGroudChannelMean(image, total)); + + cv::hal::warpAffine(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, + M, interpolation, borderType, borderValue.val); } -uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int total) +uchar getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold) { cv::Mat image_clone; cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25); @@ -357,10 +112,10 @@ uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int tota hist_array[i] = hist.at(i, 0); int length = 1; - const int length_max = 255 - m_threshold; + const int length_max = 255 - threshold; while (length < length_max) { - for (size_t i = m_threshold + 1; i < 256 - length; i++) + for (size_t i = threshold + 1; i < 256 - length; i++) { int count = 0; uint pixSum = 0; @@ -377,3 +132,199 @@ uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int tota } return 255; } + +cv::Scalar getBackGroudColor(const cv::Mat& image, int total, int threshold) +{ + if (image.channels() == 3) + { + cv::Mat image_bgr[3]; + cv::split(image, image_bgr); + + uchar bgr[3]; + for (size_t i = 0; i < 3; i++) + bgr[i] = getBackGroudChannelMean(image_bgr[i], total, threshold); + return cv::Scalar(bgr[0], bgr[1], bgr[2]); + } + else + return cv::Scalar::all(getBackGroudChannelMean(image, total, threshold)); +} + +CImageApplyDispersion dispersion_apply; +#define COLOR_SCALE_THRE 0.5 +void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, + bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion) +{ + if (src.empty()) return; + + if (isNormalCrop) + { + cv::Rect roi = cv::Rect((src.cols - dWidth) / 2, FRONT_TOP, dWidth, dHeight) & cv::Rect(0, 0, src.cols, src.rows); + dst = src(roi).clone(); + return; + } + + if (!isAutoCrop && !isDesaskew && !isFillBlank && (dWidth <= 0 || dHeight <= 0)) + { + dst = src.clone(); + return; + } + + cv::Mat resizeMat; + cv::Mat thre; + + cv::resize(src, resizeMat, cv::Size(), FX_FY, FX_FY, cv::INTER_NEAREST); + hg::threshold_Mat(resizeMat, thre, threshold); + + if (noise > 0) + cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(noise * FX_FY, 1)), + cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); + + std::vector hierarchy; + std::vector> contours; + + hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); + + for (std::vector& sub : contours) + for (cv::Point& p : sub) + p /= FX_FY; + + std::vector maxContour = hg::getMaxContour(contours, hierarchy); + + if (maxContour.empty()) + { + if (isAutoCrop) + dst = src.clone(); + else + { + cv::Rect roi = cv::Rect((src.cols - dWidth) / 2, FRONT_TOP, dWidth, dHeight) & cv::Rect(0, 0, src.cols, src.rows); + dst = src(roi).clone(); + } + return; + } + + cv::RotatedRect rect = hg::getBoundingRect(maxContour); + + if (dispersion) + { + cv::Mat mat_dispersion = src(cv::boundingRect(maxContour)); + dispersion_apply.apply(mat_dispersion, 0); + } + + cv::Scalar blankColor; + if (isFillBlank) + if (isColorBlank) + blankColor = getBackGroudColor(resizeMat, rect.size.area() * FX_FY * FX_FY, COLOR_SCALE_THRE); + else + blankColor = cv::Scalar::all(255); + else + blankColor = cv::Scalar::all(0); + + if (isAutoCrop) + if (isDesaskew) + dst = cv::Mat(cv::Size(rect.size), src.type(), blankColor); + else + dst = cv::Mat(rect.boundingRect().size(), src.type(), blankColor); + else + dst = cv::Mat(dHeight, dWidth, src.type(), blankColor); + + cv::Mat dstROI; + if (isDesaskew && rect.angle != 0) + { + cv::Point2f srcTri[4], dstTri[3]; + rect.points(srcTri); + srcTri[0].x -= 1; + srcTri[1].x -= 1; + srcTri[2].x -= 1; + + int w = rect.size.width; + int h = rect.size.height; + int x = (dst.cols - w) / 2; + int y = (dst.rows - h) / 2; + dstTri[0] = cv::Point2f(0, h); + dstTri[1] = cv::Point2f(0, 0); + dstTri[2] = cv::Point2f(w, 0); + + dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows)); + myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(0)); + } + else + { + cv::Rect bounding = cv::boundingRect(maxContour); + + if (bounding.width > dst.cols) + { + bounding.x += (bounding.width - dst.cols) / 2; + bounding.width = dst.cols; + } + + if (bounding.height > dst.rows) + { + bounding.y += (bounding.height - dst.rows) / 2; + bounding.height = dst.rows; + } + + dstROI = dst(cv::Rect((dst.cols - bounding.width) / 2, (dst.rows - bounding.height) / 2, bounding.width, bounding.height)); + src(bounding).copyTo(dstROI); + } + + if (isFillBlank) + { + if (isConvex) + { + hg::convexHull(maxContour, maxContour); + contours.clear(); + contours.push_back(maxContour); + } + + cv::Point2f srcTri[4], dstTri[3]; + int w, h; + if (isDesaskew && rect.angle != 0) + { + rect.points(srcTri); + srcTri[0].x -= 1; + srcTri[1].x -= 1; + srcTri[2].x -= 1; + w = rect.size.width; + h = rect.size.height; + } + else + { + cv::Rect bounding = rect.boundingRect(); + srcTri[0] = cv::Point(bounding.x, bounding.br().y - 1); + srcTri[1] = cv::Point(bounding.x, bounding.y); + srcTri[2] = cv::Point(bounding.br().x - 1, bounding.y); + w = bounding.width; + h = bounding.height; + } + + dstTri[0] = cv::Point2f((dstROI.cols - w) / 2 + indent, (dstROI.rows - h) / 2 + h - indent); + dstTri[1] = cv::Point2f((dstROI.cols - w) / 2 + indent, (dstROI.rows - h) / 2 + indent); + dstTri[2] = cv::Point2f((dstROI.cols - w) / 2 - indent + w, (dstROI.rows - h) / 2 + indent); + cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri); + + double* ptr_m = reinterpret_cast(warp_mat.data); + double a = ptr_m[0]; + double b = ptr_m[1]; + double c = ptr_m[2]; + double d = ptr_m[3]; + double e = ptr_m[4]; + double f = ptr_m[5]; + + int x, y; + for (std::vector& sub : contours) + for (cv::Point& p : sub) + { + x = p.x; + y = p.y; + p.x = static_cast(a * x + b * y + c); + p.y = static_cast(d * x + e * y + f); + } + + contours.push_back(std::vector()); + contours[contours.size() - 1].push_back(cv::Point(-1, dstROI.rows - 1)); + contours[contours.size() - 1].push_back(cv::Point(-1, -1)); + contours[contours.size() - 1].push_back(cv::Point(dstROI.cols, -1)); + contours[contours.size() - 1].push_back(cv::Point(dstROI.cols, dst.rows)); + hg::fillPolys(dstROI, contours, blankColor); + } +} diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.h b/huagao/ImageProcess/ImageApplyAutoCrop.h index e1f1f4ae..63fa3616 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.h +++ b/huagao/ImageProcess/ImageApplyAutoCrop.h @@ -2,27 +2,31 @@ * ==================================================== * 功能:自动裁剪、纠偏、除黑底 - * 作者:刘丁维 - * 生成时间:2020/4/21 + * 作者:刘丁绿 + * 生成时间_020/4/21 * 最近修改时间:2020/4/21 v1.0 - 2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用) - 2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度。 - 2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG。 - 2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG。 - 2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏) - 2020/11/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底。 - 2021/06/18 v1.3.1 调整默认noise为8。 - 2021/07/01 v1.3.2 修复 无裁切情况下,自适应颜色除黑底不生效的BUG。 - 2021/07/08 v1.3.3 完善流程。当无法定位内容时,且为固定幅面裁切,则返回按照固定幅面进行裁切的结果。 - 2021/07/08 v1.3.4 调整参数,让消除背景噪声不对纵向像素造成影响。 - 2021/07/09 v1.3.5 增加normalCrop机制,当m_isCrop m_isDesaskew m_isFillBlank均为false时可选用,实现传统裁切。 - 2021/07/13 v1.3.6 调整normalCrop逻辑,当normalCrop为true时,m_isCrop m_isDesaskew m_isFillBlank失效。 - 2021/07/19 v1.3.7 调整仿射变换模式为INTER_LINEAR。 - 2021/07/22 v1.3.8 修复第二次寻边,找不到外界轮廓会导致崩溃的BUG。 - 2021/08/02 v1.3.9 精细化除黑底算法,可以应对只有条纹内容的黑色图像。 - 2021/10/08 v1.3.10 优化算法,用腐蚀代替绘制实现缩进,提高整体算法效率。 - 2021/10/19 v1.3.11 解决一些极端情况,例如纸张自然0角度,纸张定格在图像顶部的处理。 - * 版本号:v1.3.11 + 2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用_ + 2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度 + 2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG + 2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG + 2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏_ + 2020/11/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底 + 2021/06/18 v1.3.1 调整默认noise + 2021/07/01 v1.3.2 修复 无裁切情况下,自适应颜色除黑底不生效的BUG + 2021/07/08 v1.3.3 完善流程。当无法定位内容时,且为固定幅面裁切,则返回按照固定幅面进行裁切的结果 + 2021/07/08 v1.3.4 调整参数,让消除背景噪声不对纵向像素造成影响 + 2021/07/09 v1.3.5 增加normalCrop机制,当m_isCrop m_isDesaskew m_isFillBlank均为false时可选用,实现传统裁切 + 2021/07/13 v1.3.6 调整normalCrop逻辑,当normalCrop为true时,m_isCrop m_isDesaskew m_isFillBlank失效 + 2021/07/19 v1.3.7 调整仿射变换模式为INTER_LINEAR + 2021/07/22 v1.3.8 修复第二次寻边,找不到外界轮廓会导致崩溃的BUG + 2021/08/02 v1.3.9 精细化除黑底算法,可以应对只有条纹内容的黑色图像 + 2021/10/08 v1.3.10 优化算法,用腐蚀代替绘制实现缩进,提高整体算法效率 + 2021/10/19 v1.3.11 解决一些极端情况,例如纸张自然0角度,纸张定格在图像顶部的处理 + 2021/10/19 v1.3.12 微调裁切纠偏像素精度 + 2022/04/24 v1.4 重构算法,增加除色散功能 + 2022/05/03 v1.4.1 完善逻辑 + 2022/06/09 v1.4.2 修复获取文稿底色时,threshold值,设为固定值0.5 + * 版本号:v1.4.2 * ==================================================== */ @@ -37,21 +41,21 @@ class CImageApplyAutoCrop : public CImageApply public: CImageApplyAutoCrop(); - /* - * isCrop [in]:自动幅面裁剪使能,true自动裁剪,false为固定裁剪 + * isCrop [in]:自动幅面裁剪使能,true自动裁剪,false为固定裁剿 * isDesaskew [in]:自动纠偏使能,true自动纠偏,false为不纠偏 * isFillBlank [in]:黑底填充使能,true为填充,false为不填充 - * fixedSize [in]:固定幅面尺寸,当isCrop为false时生效,结果尺寸按fixedSize大小输出,单位像素 + * fixedSize [in]:固定幅面尺寸,当isCrop为false时生效,结果尺寸按fixedSize大小输出,单位像紿 * isConvex [in]:黑底填充时的填充方式,true为凸多边形填充,false为凹多边形填充,默认true * isFillColor [in]:黑底填充时采用自适应色彩填充,false为白色填充,true为自适应文稿底色填充,默认false - * threshold [in]:二值化阈值,取值范围(0, 255),默认40 - * noise [in]:除噪像素,能够消除noise宽度的背景竖条纹干扰,默认2 - * indent [in]:轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认5 - * normalCrop [in]:为true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效,固定裁切采用最传统的裁切方式,默认false + * threshold [in]:二值化阈值,取值范囿0, 255),默访0 + * noise [in]:除噪像素,能够消除noise宽度的背景竖条纹干扰,默访 + * indent [in]:轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默访 + * normalCrop [in]:为true时,m_isCrop m_isDesaskew m_isFillBlank失效,固定裁切采用最传统的裁切方式,默认false + * dispersion [in]:为true时,除色散;false时不除色散。默认为true */ CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, - bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false); + bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, bool dispersion = true); virtual ~CImageApplyAutoCrop(); @@ -67,12 +71,10 @@ public: bool isConvexHull() { return m_isConvexHull; } + cv::RotatedRect getROI() { return m_rect; } + double threshold() { return m_threshold; } - cv::RotatedRect& rotatedROI() { return m_rect; } - - const std::vector& rotatedROIs() { return m_rects; } - int noise() { return m_noise; } int indent() { return m_indent; } @@ -97,10 +99,7 @@ public: void setFixedSize(cv::Size size) { m_fixedSize = size; } -private: - cv::Scalar getBackGroudColor(const cv::Mat& image, int total); - - uchar getBackGroudChannelMean(const cv::Mat& gray, int total); + void setDispersion(bool enable) { m_isDispersion = enable; } private: bool m_isCrop; @@ -108,16 +107,19 @@ private: bool m_isFillBlank; bool m_isConvexHull; bool m_isFillColor; + bool m_isDispersion; double m_threshold; int m_noise; int m_indent; - bool m_normalCrop; //为true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效,固定裁切采用最传统的裁切方式 + bool m_normalCrop; //为true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效,固定裁切采用最传统的裁切方弿 cv::Size m_fixedSize; cv::RotatedRect m_rect; - std::vector m_maxContour; std::vector m_rects; + std::vector m_maxContour; }; -#endif // !IMAGE_APPLY_AUTO_CROP_H +void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, + bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false, bool dispersion = true); +#endif // !IMAGE_APPLY_AUTO_CROP_H diff --git a/huagao/ImageProcess/ImageApplyHSVCorrect.cpp b/huagao/ImageProcess/ImageApplyHSVCorrect.cpp index 9580057b..2cb4673f 100644 --- a/huagao/ImageProcess/ImageApplyHSVCorrect.cpp +++ b/huagao/ImageProcess/ImageApplyHSVCorrect.cpp @@ -1,164 +1,173 @@ #include "ImageApplyHSVCorrect.h" #include -CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr) - : m_table(new uint[256 * 256 * 256]) +CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr, uint alpha) + : m_table(new uint[256 * 256 * 256]) { - initLUT(); - switch (mode) - { - case CImageApplyHSVCorrect::Red_Removal: - set_HSV_value(std::pair(0, 63), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); - set_HSV_value(std::pair(200, 255), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); - break; - case CImageApplyHSVCorrect::LowSaturation_Removal: - set_HSV_value(std::pair(0, 255), std::pair(0, 30), std::pair(0, 255), bgr, cvtColor); - break; - default: - break; - } + initLUT(); + uint temp; + switch (mode) + { + case CImageApplyHSVCorrect::Red_Removal: + set_HSV_value(std::pair(0, 63), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); + set_HSV_value(std::pair(200, 255), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); + break; + case CImageApplyHSVCorrect::LowSaturation_Removal: + if (alpha < 0) + temp = 35; + else + temp = alpha; + set_HSV_value(std::pair(0, 255), std::pair(0, temp), std::pair(0, 255), bgr, cvtColor); + break; + case CImageApplyHSVCorrect::FXB_Colour_Cast: + set_HSV_value(std::pair(45, 105), std::pair(0, 255), std::pair(0, 255), 0x00FFFFFF, true); + set_HSV_value(std::pair(180, 235), std::pair(0, 255), std::pair(0, 255), 0x00FFFFFF, true); + set_HSV_value(std::pair(0, 30), std::pair(0, 50), std::pair(0, 255), 0x00FFFFFF, true); + break; + default: + break; + } } CImageApplyHSVCorrect::~CImageApplyHSVCorrect() { - delete[] m_table; + delete[] m_table; } void CImageApplyHSVCorrect::apply(cv::Mat& pDib, int side) { - (void)side; - if (pDib.empty() || pDib.channels() != 3) return; + (void)side; + if (pDib.empty() || pDib.channels() != 3) return; #if 0 - uchar* src = pDib.data; - cv::Mat z = cv::Mat::zeros(pDib.size(), CV_8UC3); - uchar* dst = z.data; + uchar* src = pDib.data; + cv::Mat z = cv::Mat::zeros(pDib.size(), CV_8UC3); + uchar* dst = z.data; - int bytesPerLine = pDib.cols * pDib.channels(); - for (size_t i = 0, rows = pDib.rows; i < rows; i++) - { - uchar* ptr = pDib.ptr(i); - for (size_t j = 0, cols = pDib.cols; j < cols; j++) - { - int offset = i * 3; - int index = *reinterpret_cast(ptr + offset) & 0x00ffffff; - uint color = m_table[index]; - *reinterpret_cast(dst + offset) |= color; - } - } - pDib = z; + int bytesPerLine = pDib.cols * pDib.channels(); + for (size_t i = 0, rows = pDib.rows; i < rows; i++) + { + uchar* ptr = pDib.ptr(i); + for (size_t j = 0, cols = pDib.cols; j < cols; j++) + { + int offset = i * 3; + int index = *reinterpret_cast(ptr + offset) & 0x00ffffff; + uint color = m_table[index]; + *reinterpret_cast(dst + offset) |= color; + } + } + pDib = z; #else - cv::Mat bgra; - cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA); + cv::Mat bgra; + cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA); - long total = bgra.total(); - uint* ptr = bgra.ptr(); - for (long i = 0; i < total; i++) - ptr[i] = m_table[ptr[i] & 0x00FFFFFF]; + long total = bgra.total(); + uint* ptr = bgra.ptr(); + for (long i = 0; i < total; i++) + ptr[i] = m_table[ptr[i] & 0x00FFFFFF]; - cv::cvtColor(bgra, pDib, cv::COLOR_BGRA2BGR); + cv::cvtColor(bgra, pDib, cv::COLOR_BGRA2BGR); #endif } void CImageApplyHSVCorrect::apply(std::vector& mats, bool isTwoSide) { - (void)isTwoSide; - int i = 0; - for (cv::Mat& var : mats) { - if (i != 0 && isTwoSide == false) - break; - if (!var.empty()) - apply(var, 0); - i++; - } + (void)isTwoSide; + int i = 0; + for (cv::Mat& var : mats) { + if (i != 0 && isTwoSide == false) + break; + if (!var.empty()) + apply(var, 0); + i++; + } } void CImageApplyHSVCorrect::initLUT() { #if 0 - uchar h, s, v; + uchar h, s, v; #endif - for (uint b = 0; b < 256; b++) - for (uint g = 0; g < 256; g++) - for (uint r = 0; r < 256; r++) - { + for (uint b = 0; b < 256; b++) + for (uint g = 0; g < 256; g++) + for (uint r = 0; r < 256; r++) + { #if 0 - RGB_2_HSV_full(r, g, b, h, s, v); + RGB_2_HSV_full(r, g, b, h, s, v); - uint index = b | (g << 8) | (r << 16); - if (h < 12 || h > 245) - m_table[index] = index & 0x00ffffff; - else - m_table[index] = (v | (v << 8) | (v << 16)) & 0x00ffffff; + uint index = b | (g << 8) | (r << 16); + if (h < 12 || h > 245) + m_table[index] = index & 0x00ffffff; + else + m_table[index] = (v | (v << 8) | (v << 16)) & 0x00ffffff; #else - m_table[b | (g << 8) | (r << 16)] = b | (g << 8) | (r << 16); + m_table[b | (g << 8) | (r << 16)] = b | (g << 8) | (r << 16); #endif - } + } } void CImageApplyHSVCorrect::set_single(const uint src_b, const uint src_g, const uint src_r, - const uint dst_b, const uint dst_g, const uint dst_r) + const uint dst_b, const uint dst_g, const uint dst_r) { - m_table[src_b | (src_g << 8) | (src_r << 16)] = dst_b | (dst_g << 8) | (dst_r << 16); + m_table[src_b | (src_g << 8) | (src_r << 16)] = dst_b | (dst_g << 8) | (dst_r << 16); } void CImageApplyHSVCorrect::set_HSV_value(const std::pair& range_h, - const std::pair& range_s, - const std::pair& range_v, - uint bgr, bool cvtGray) + const std::pair& range_s, + const std::pair& range_v, + uint bgr, bool cvtGray) { - uchar h, s, v; - for (int b = 0; b < 256; b++) - for (int g = 0; g < 256; g++) - for (int r = 0; r < 256; r++) - { - RGB_2_HSV_full(r, g, b, h, s, v); - if (contained(h, range_h) && contained(s, range_s) && contained(v, range_v)) - { - if (cvtGray) - { - int a = (b + g + r) / 3 * 0x00010101; - m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = (b + g + r) / 3 * 0x00010101; - } - else - m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff; - } - } + uchar h, s, v; + for (int b = 0; b < 256; b++) + for (int g = 0; g < 256; g++) + for (int r = 0; r < 256; r++) + { + RGB_2_HSV_full(r, g, b, h, s, v); + if (contained(h, range_h) && contained(s, range_s) && contained(v, range_v)) + { + if (cvtGray) + { + int a = (b + g + r) / 3 * 0x00010101; + m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = (b + g + r) / 3 * 0x00010101; + } + else + m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff; + } + } } void CImageApplyHSVCorrect::set_table(const uint* table) { - memcpy(m_table, table, 256 * 256 * 256); + memcpy(m_table, table, 256 * 256 * 256 * sizeof(uint)); } bool CImageApplyHSVCorrect::contained(uchar value, const std::pair& range) { - return value >= range.first && value <= range.second; + return value >= range.first && value <= range.second; } void CImageApplyHSVCorrect::RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar& s, uchar& v) { - int minn = cv::min(r, cv::min(g, b)); - int maxx = cv::max(r, cv::max(g, b)); - v = static_cast(maxx); //V + int minn = cv::min(r, cv::min(g, b)); + int maxx = cv::max(r, cv::max(g, b)); + v = static_cast(maxx); //V - int delta = maxx - minn; - float _h; - if (maxx == 0) - { - h = s = v = 0; - return; - } - else - s = static_cast(delta * 255 / maxx); + int delta = maxx - minn; + float _h; + if (maxx == 0) + { + h = s = v = 0; + return; + } + else + s = delta; - if (r == maxx) - _h = static_cast(g - b) / static_cast(delta); - else if (g == maxx) - _h = 2 + static_cast(b - r) / static_cast(delta); - else - _h = 4 + static_cast(r - g) / static_cast(delta); - - float __h = _h * 42.6666666667f; - h = (__h >= 0) ? static_cast(__h) : static_cast(__h + 256); -} + if (r == maxx) + _h = static_cast(g - b) / static_cast(delta); + else if (g == maxx) + _h = 2 + static_cast(b - r) / static_cast(delta); + else + _h = 4 + static_cast(r - g) / static_cast(delta); + float __h = _h * 42.6666666667f; + h = (__h >= 0) ? static_cast(__h) : static_cast(__h + 256); +} \ No newline at end of file diff --git a/huagao/ImageProcess/ImageApplyHSVCorrect.h b/huagao/ImageProcess/ImageApplyHSVCorrect.h index 2e5806d3..7336bdac 100644 --- a/huagao/ImageProcess/ImageApplyHSVCorrect.h +++ b/huagao/ImageProcess/ImageApplyHSVCorrect.h @@ -4,12 +4,16 @@ * ܣɫͼɫУLUTʵ֣ԤBGRֵHVSBGRԭͼвֵУ * ߣά * ʱ䣺2020/3/21 - * ޸ʱ䣺v1.0 2020/03/21 - v1.1 2020/06/15 ЧHSVȡֵΧ - v1.2 2021/08/02 ڴָ룬ӦROIͼڴƫơ - v1.3 2021/08/26 滻⿨Red_Removalʵַ - v1.4 2022/04/22 ӹܣ֧ػҶֵԭɫأɾĬϹ캯УѡDeafaultLowSaturation_Removal - * 汾ţv1.4 + * ޸ʱ䣺v1.0 2020/03/21 + v1.1 2020/06/15 ЧHSVȡֵΧ + v1.2 2021/08/02 ڴָ룬ӦROIͼڴƫơ + v1.3 2021/08/26 滻⿨Red_Removalʵַ + v1.4 2022/04/22 ӹܣ֧ػҶֵԭɫأɾĬϹ캯УѡDeafaultLowSaturation_Removal + v1.4.1 2022/04/25 ͣݷԽ硣 + v1.4.2 2022/06/09 ޸һڴСĴ + v1.5 2022/08/22 Ͷȼ㷽ʽ캯Ӳalpha΢ģʽIJ + v1.5.1 2022/09/23 ӷƫɫԤ跽 + * 汾ţv1.5 * * ==================================================== */ @@ -19,22 +23,24 @@ #include "ImageApply.h" -class CImageApplyHSVCorrect : public CImageApply +class CImageApplyHSVCorrect : public CImageApply { public: enum CorrectOption { Deafault, //ĬϣκγɫЧ LowSaturation_Removal, //ͱͶ - Red_Removal //ɫɫH:[0, 85][170, 255],S:[10, 255],V:[120,255] + Red_Removal, //ɫɫH:[0, 85][170, 255],S:[10, 255],V:[120,255] + FXB_Colour_Cast //ƫɫ }; public: /* * mode [in]:Ԥɫģʽ * cvtColor [in]:ʹĬֵʹûҶֵtrueΪҶֵfalseΪĬֵ - * bgr:[in] uintʾBGRֵBڵλRڸλcvtGray ΪfalseʱЧ) + * bgr [in] uintʾBGRֵBڵλRڸλcvtGray ΪfalseʱЧ) + * alpha [int] ڵLowSaturation_RemovalģʽǿȡalphaΪʱͶĬΪ[0, 35]alphaΪǸʱͶΪ[0, alpha] */ - CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Deafault, bool cvtColor = false, uint bgr = 0x00FFFFFF); + CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Deafault, bool cvtColor = false, uint bgr = 0x00FFFFFF, uint alpha = -1); virtual ~CImageApplyHSVCorrect(); @@ -90,5 +96,4 @@ private: uint* m_table; }; -#endif - +#endif \ No newline at end of file diff --git a/huagao/huagaods.cpp b/huagao/huagaods.cpp index 04a506d4..65078a1c 100644 --- a/huagao/huagaods.cpp +++ b/huagao/huagaods.cpp @@ -72,6 +72,7 @@ enum class CapTypeEx : unsigned short { TwEx_IEnMultiOutPutType = 0x8113, TwEx_IFixedPaper = 0x8114, TwEx_IHighImageQuality = 0x8115, + TwEx_IHsvFilter = 0x8116 }; enum class PaperSizeEx : unsigned short { @@ -1199,6 +1200,8 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_scanparam->multi_output_red = 0;//Dzɫģʽ¶ m_scanparam->detachnoise.is_detachnoise = false; m_scanparam->fadeback = false; + m_scanparam->hsvFilter = 0; + m_scanparam->hsvcorrect = 0; //if (mech == PixelType::BlackWhite) //{ // if (m_scanparam->filter == (uint8)Filter::None && m_scanparam->enhance_color == Enchace_Color::Enhance_None) @@ -2287,6 +2290,21 @@ Result HuagaoDs::identityOpenDs(const Identity&) { } return CapSupGetAllResetEx(msg, data, m_scanparam->is_split, false); }; + + m_query[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = msgSupportGetAllSetReset; + m_caps[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = [this](Msg msg, Capability& data)->Result { + //CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropModel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); + if (Msg::Set == msg) { + auto mech = data.currentItem(); + if (m_scanparam->pixtype != 2)//color + return badValue(); + + m_scanparam->hsvFilter = mech?1:0; + return success(); + } + bool hsv_v=(bool)(m_scanparam->hsvFilter); + return CapSupGetAllResetEx(msg, data, hsv_v, false); + }; #ifdef UV m_query[(CapType)(CapTypeEx::TwEx_UVModel)] = msgSupportGetAllSetReset; m_caps[(CapType)(CapTypeEx::TwEx_UVModel)] = [this](Msg msg, Capability& data)->Result { diff --git a/huagao/huagaotwds.rc b/huagao/huagaotwds.rc index daebd817d07a5f30a5f0a8dc68703ccfecbabc07..d26f6e0ae79cdc5603a32a782a58f6ff208b5977 100644 GIT binary patch delta 139 zcmdnAiuuSw<_%T`lMfi&o4n7~Wb!$qYm>yZHeWG$!m_!+#))t89e$3<^BgrC@A^lU zE~+bP+8vxS%_+U8Nr^#+!IQy-!I>c*h`kw{fV3lnA44!hID;!g5Rmo&(yk043~oSm mJ`5p~4J~XZCpgRS8Zj6#m;-eiG8izJOg2=~-2A{Rs0#pu$SIZp delta 351 zcmX@Ika^Q8<_%T`oZ-=G)mHJ$Jyw$+%F1#YFz7HCf#Bpu{qV_F2KOePGgo5r^PfCH zM26pp!3-*G3ZyM3+gs>^rEkmvN=pfXq+$Bap$d{G`xsuEd_YD|*oDEF!Gpn(A&9}1 z!4J%Go-Ak|Iypd{XYv6<2Vo-yLk3HrE<>OhAR5TuENCRpDr7V*Dce8bccnf<%Cz0V zXBzU;CU=?22s#1Ha%S*m@MmxX!e9p1$qPM7fo`w>>osNoxxj+Kc=AViQx1?ulWB$V zAdTF?V9Q;A8p9_CDp*cd@U!AJf;t?iZSp~5Yp{kHNmon38l1syb_Cl2($L^#F7=kA&y6aE=W1;{ORfLN&gfqA@1Th3NcmQcv ch7blf22TbbhLFjH`ofbh7_n{sXA&n10BGhEqyPW_ delta 17 ZcmbQTjPcGA#tky2lO#Ac-!Zk21pq+A28jRw diff --git a/huagao/stdafx.h b/huagao/stdafx.h index 72789f414d4300e9c121c9f25e03b5a259a1d4e5..6b01789f0d2539655552c1bd5ea9af5a323a9235 100644 GIT binary patch delta 43 zcmX?fobk|c#tkhTtR@Tw3CIcFmevT From 0a294745c27ac49df84c66a08e79814c60ed791e Mon Sep 17 00:00:00 2001 From: lovelyyoung <1002639516@qq.com> Date: Tue, 15 Nov 2022 15:32:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E4=B8=8D=E8=BF=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- huagao/huagaods.cpp | 1654 +------------------------------------------ 1 file changed, 1 insertion(+), 1653 deletions(-) diff --git a/huagao/huagaods.cpp b/huagao/huagaods.cpp index dfaf9318..db6823ec 100644 --- a/huagao/huagaods.cpp +++ b/huagao/huagaods.cpp @@ -3140,1656 +3140,4 @@ void HuagaoDs::saveGscanCapSetting() std::string savepath = TCHAR2STRING(szIniFile); js.SaveGscancapJson(*m_scanparam, savepath); //js.WriteJsonArrayToFile(vc, savepath); -} - m_query[CapType::FeederLoaded] = msgSupportGetAll; - m_caps[CapType::FeederLoaded] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::FeederLoaded)); - return CapSupGetAll(msg, data, Bool(scanner->Get_Scanner_PaperOn()), Bool(scanner->Get_Scanner_PaperOn())); - }; - - m_query[CapType::Indicators] = msgSupportGetAllSetReset; - m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::Indicators), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto show = data.currentItem(); - m_bIndicator = show; - return success(); - } - return CapSupGetAllReset(msg, data, { FALSE,TRUE }, m_bIndicator, TRUE, m_bIndicator ? 1 : 0, 1); - }; - - m_query[CapType::CustomDsData] = msgSupportGetAll; - m_caps[CapType::CustomDsData] = [this](Msg msg, Capability& data) -> Result { - return CapSupGetAllEx(msg, data, Bool(true), Bool(true)); - }; - - m_query[CapType::EnableDsUiOnly] = msgSupportGetAll; - m_caps[CapType::EnableDsUiOnly] = std::bind(enmGet, _1, _2, Bool(true)); - - m_query[CapType::PaperDetectable] = msgSupportGetAll; - m_caps[CapType::PaperDetectable] = std::bind(oneValGet, _1, _2, Bool(true)); - - m_query[CapType::FeederEnabled] = msgSupportGetAllSetReset; - m_caps[CapType::FeederEnabled] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::FeederEnabled), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_bFeederEnabled = mech; - return success(); - } - return CapSupGetAllReset(msg, data, m_bFeederEnabled, Bool(true)); - }; - - m_query[CapType::Duplex] = msgSupportGetAll; - m_caps[CapType::Duplex] = std::bind(oneValGet, _1, _2, Duplex::OnePass); - - m_query[CapType::DuplexEnabled] = msgSupportGetAllSetReset; - m_caps[CapType::DuplexEnabled] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::DuplexEnabled), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - bool mech = data.currentItem(); - m_scanparam->is_duplex = mech; - if (!mech){ - m_scanparam->is_backrotate180 = 0;//汳ת180㲻 - m_scanparam->is_switchfrontback = 0; - m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = m_scanparam->en_fold = 0; - } - return success(); - } - return CapSupGetAllReset(msg, data, m_scanparam->is_duplex, Bool(true)); - }; - - m_query[CapType::AutoFeed] = msgSupportGetAllSetReset; - m_caps[CapType::AutoFeed] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::AutoFeed), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_bAutoFeed = mech; - return success(); - } - return CapSupGetAllReset(msg, data, { false,true }, m_bAutoFeed, true, m_bAutoFeed ? 1 : 0, 1); - }; - m_query[CapType::IImageFileFormat] = msgSupportGetAllSetReset; - m_caps[CapType::IImageFileFormat] = [this](Msg msg, Capability& data) -> Result { - CapabilityPrintf(msg, enum2str(CapType::IImageFileFormat), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech == ImageFileFormat::Bmp || - mech == ImageFileFormat::Tiff || - mech == ImageFileFormat::Jfif) { - m_capImageFileFormat = mech; - return success(); - } - else - return badValue(); - } - return CapSupGetAllReset < ImageFileFormat, ImageFileFormat, CapType::IImageFileFormat>(msg, data, { ImageFileFormat::Bmp, ImageFileFormat::Tiff,ImageFileFormat::Jfif }, - m_capImageFileFormat, ImageFileFormat::Bmp, m_capImageFileFormat == ImageFileFormat::Bmp ? 0 : (m_capImageFileFormat == ImageFileFormat::Tiff ? 1 : 2), 0); - }; - - //custom define - m_query[CapType::IAutomaticDeskew] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticDeskew] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IAutomaticDeskew), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto atuodsw = data.currentItem(); - m_scanparam->autodescrew = (bool)atuodsw; - return success(); - } - return CapSupGetAllReset(msg, data, m_scanparam->autodescrew, true); - }; - - m_query[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_SwitchFrontBack), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if ((!m_scanparam->is_duplex) && mech == TRUE) - return badValue(); - m_scanparam->is_switchfrontback = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_switchfrontback, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->is_switchfrontback, (Bool)false, m_scanparam->is_switchfrontback ? 1 : 0, 0); - }; - - m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IAutomaticRotate), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->is_autotext = (bool)mech; - if (mech) - m_scanparam->imageRotateDegree = 0.0f; - return success(); - } - return CapSupGetAllReset(msg, data, m_scanparam->is_autotext, false); - }; - - m_query[CapType::IAutomaticCropUsesFrame] = msgSupportGetAll; - m_caps[CapType::IAutomaticCropUsesFrame] = [this](Msg msg, Capability& data)->Result { - return CapSupGetAll(msg, data, m_scanparam->is_autocrop, false); - }; - - m_query[CapType::AutoScan] = msgSupportGetAllSetReset; - m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::AutoScan), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto autoscan = data.currentItem(); - m_autoscan = autoscan; - return success(); - } - //return CapSupGetAllReset(msg, data, { FALSE,TRUE }, m_autoscan, Bool(true), m_autoscan ? 1 : 0, 0); - return CapSupGetAllReset(msg, data, m_autoscan, TRUE); - }; - - m_query[CapType(CapTypeEx::TwEx_IHighImageQuality)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::TwEx_IHighImageQuality)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IHighImageQuality), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto tmp = data.currentItem(); - m_scanparam->is_high_imagequality = tmp; - return success(); - } - //return CapSupGetAllReset(msg, data, { FALSE,TRUE }, m_autoscan, Bool(true), m_autoscan ? 1 : 0, 0); - return CapSupGetAllResetEx(msg, data, m_scanparam->is_high_imagequality, false); - }; - - m_query[CapType::IAutoSize] = msgSupportGetAllSetReset; - m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IAutoSize), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto autosize = data.currentItem(); - if (autosize == AutoSize::Auto) { - if (m_scanparam->papertype == (BYTE)PaperSize::UsStatement) { - m_scanparam->is_autocrop = 0; - m_autoboarderdetcet = false; - } - else { - m_scanparam->is_autocrop = 1; - m_scanparam->papertype = (BYTE)Twpp::PaperSize::None; - m_scanparam->paperAlign = PaperAlign::Rot0; - m_autoboarderdetcet = true; - } - } - else { - m_autoboarderdetcet = false; - m_scanparam->is_autocrop = 0; - } - m_autosize = (UInt16)autosize; - return success(); - } - return CapSupGetAllReset(msg, data, { AutoSize::None, AutoSize::Auto }, m_autosize, AutoSize::None, (m_autosize == (UInt16)AutoSize::Auto) ? 1 : 0, 0); - }; - - m_query[CapType::IAutomaticBorderDetection] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticBorderDetection] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IAutomaticBorderDetection), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto autodetectborder = data.currentItem(); - if (autodetectborder) { - if (m_scanparam->papertype != (BYTE)PaperSize::UsStatement) { - m_scanparam->is_autocrop = true; - m_scanparam->papertype = (BYTE)Twpp::PaperSize::None; - m_scanparam->paperAlign = PaperAlign::Rot0; - m_autosize = (UInt16)AutoSize::Auto; - } - } - else { - m_autosize = (UInt16)AutoSize::None; - } - m_autoboarderdetcet = autodetectborder; - return success(); - } - return CapSupGetAllReset(msg, data, { false,true }, m_autoboarderdetcet, false, m_autoboarderdetcet ? 1 : 0, 0); - }; - - //m_query[CapType::IImageMerge] = msgSupportGetAllSetReset; - //m_caps[CapType::IImageMerge] = [this](Msg msg, Capability& data)->Result { - // if (Msg::Set == msg) { - // auto autocrop = data.currentItem(); - // m_scanparam->en_fold = (BYTE)autocrop; - // if ((UInt16)autocrop != 0){ - // m_scanparam->is_duplex = 1; - // m_scanparam->autodescrew = 1;//ϲʱ ĬԶƫ - // m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = 0; - // } - // return success(); - // } - // return CapSupGetAllResetEx(msg, data, m_scanparam->en_fold, 0); - //}; - - m_query[CapType(CapTypeEx::TwEx_EnFold)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::TwEx_EnFold)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_EnFold), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto autocrop = data.currentItem(); - m_scanparam->en_fold = (Int32)autocrop; - if ((UInt16)autocrop != 0) { - m_scanparam->is_duplex = 1; - m_scanparam->autodescrew = 1;//ϲʱ ĬԶƫ - m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = 0; - } - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->en_fold, 0); - //return CapSupGetAllResetEx(msg, data, { 0,1 }, m_scanparam->en_fold, 0, m_scanparam->en_fold ? 1 : 0, 0); - }; - - m_query[CapType::IAutoDiscardBlankPages] = msgSupportGetAllSetReset; - m_caps[CapType::IAutoDiscardBlankPages] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IAutoDiscardBlankPages), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if ((mech == DiscardBlankPages::Auto) || (mech == DiscardBlankPages::Disabled)||((int)mech == 65535)) - { - if ((int)mech == 65535 || mech == DiscardBlankPages::Auto) - { - m_scanparam->is_autodiscradblank_normal = 1; - m_scanparam->is_duplex = 1; - m_scanparam->en_fold = 0; - m_scanparam->is_autodiscradblank_vince = 0; - } - else - { - m_scanparam->is_autodiscradblank_normal = 0; - } - return success(); - } - return badValue(); - } - DiscardBlankPages autodiscradblank; - if (Msg::GetDefault == msg || (Msg::Reset == msg)) { - m_scanparam->is_autodiscradblank_normal = false; - } - m_scanparam->is_autodiscradblank_normal ? (autodiscradblank = DiscardBlankPages::Auto) : (autodiscradblank = DiscardBlankPages::Disabled); - return CapSupGetAllReset(msg, data, autodiscradblank, DiscardBlankPages::Disabled); - }; - - /*costom caps*/ - //հҳƱ - m_query[(CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IAutoDiscardBlankVince), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->is_autodiscradblank_vince = mech; - if (mech) { - m_scanparam->is_duplex = 1; - m_scanparam->en_fold = 0; - m_scanparam->is_autodiscradblank_normal = 0; - } - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_autodiscradblank_vince, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->is_autodiscradblank_vince, Bool(false), m_scanparam->is_autodiscradblank_vince ? 1 : 0, 0); - - }; - - m_query[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IBackRotate180), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech) - { - if (!m_scanparam->is_duplex) - { - return badValue(); - } - } - m_scanparam->is_backrotate180 = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_backrotate180, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->is_backrotate180, Bool(false), m_scanparam->is_backrotate180 ? 1 : 0, 0); - }; - - //ڿ - m_query[(CapType)(CapTypeEx::TwEx_IFillBackground)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IFillBackground)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillBackground), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->fillbackground = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->fillbackground, true); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->fillbackground, Bool(true), m_scanparam->fillbackground ? 1 : 0, 1); - }; - - //üƫ - m_query[(CapType)(CapTypeEx::TwEx_CroporDesaskewIndent)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_CroporDesaskewIndent)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CroporDesaskewIndent), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if ((mech > 30 || mech < 5) && ((bool)m_scanparam->is_autocrop == true)) - return badValue(); - m_scanparam->indent = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->indent, 5); - }; - - //Զü - m_query[(CapType)(CapTypeEx::TwEx_CropNoise)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_CropNoise)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropNoise), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if ((mech > 20 || mech < 0) && ((bool)m_scanparam->is_autocrop == true)) - return badValue(); - m_scanparam->noise = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->noise, 8); - }; - //Զк;ƫĶֵֵ - m_query[(CapType)(CapTypeEx::TwEx_CroporDesaskewThreshold)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_CroporDesaskewThreshold)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CroporDesaskewThreshold), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech > 50 || mech < 30) - return badValue(); - m_scanparam->AutoCrop_threshold = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->AutoCrop_threshold, 40); - }; - //ڿ䷽ʽ - m_query[(CapType)(CapTypeEx::TwEx_FillBackgroundMode)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_FillBackgroundMode)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_FillBackgroundMode), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->is_convex = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_convex, Bool(true)); - }; - // - m_query[(CapType)(CapTypeEx::TwEx_IFillHole)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IFillHole)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillHole), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->fillhole.is_fillhole = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->fillhole.is_fillhole, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->fillhole.is_fillhole, Bool(false), m_scanparam->fillhole.is_fillhole ? 1 : 0, 0); - }; - - m_query[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillHoleRatio), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech > 0 && mech < 50) { - m_scanparam->fillhole.fillholeratio = (int)mech; - m_scanparam->fillholeratio_up = m_scanparam->fillholeratio_down = m_scanparam->fillholeratio_left = m_scanparam->fillholeratio_right = int(mech); - return success(); - } - return badValue(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->fillhole.fillholeratio, 10); - }; - //Ż - m_query[(CapType)(CapTypeEx::TwEx_IDetachNoise)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IDetachNoise)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IDetachNoise), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech) { - if (m_scanparam->pixtype != 0) - return badValue(); - } - m_scanparam->detachnoise.is_detachnoise = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->detachnoise.is_detachnoise, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->detachnoise.is_detachnoise, FALSE, m_scanparam->detachnoise.is_detachnoise ? 1 : 0, 0); - }; - - m_query[(CapType)(CapTypeEx::TwEx_IDetachNoiseValue)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IDetachNoiseValue)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IDetachNoiseValue), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech > 9 && mech < 51) { - m_scanparam->detachnoise.detachnoise = (int)mech; - return success(); - } - return badValue(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->detachnoise.detachnoise, 10); - }; - //Ƴ - m_query[(CapType)(CapTypeEx::TwEx_IFadeBack)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IFadeBack)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFadeBack), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech) - { - if (m_scanparam->pixtype != 2) - return badValue(); - } - m_scanparam->fadeback = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->fadeback, false); - }; - - m_query[(CapType)(CapTypeEx::TwEx_IFadeBackValue)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IFadeBackValue)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFadeBackValue), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech > 0 && mech < 129) { - m_scanparam->fadeback_range = (int)mech; - return success(); - } - return badValue(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->fadeback_range, 40); - }; - // - m_query[(CapType)(CapTypeEx::TwEx_IMultiOutputRed)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IMultiOutputRed)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IMultiOutputRed), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype == (BYTE)PixelType::Rgb &&(!m_scanparam->en_multi_output)) - m_scanparam->multi_output_red = mech; - else - return badValue(); - //m_scanparam->multi_output_red = 0;//Dzɫ ʹö - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->multi_output_red, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->multi_output_red, FALSE, m_scanparam->multi_output_red ? 1 : 0, 0); - }; - //ʹ - m_query[(CapType)(CapTypeEx::TwEx_IEnMultiOutPut)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IEnMultiOutPut)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnMultiOutPut), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype == (BYTE)PixelType::Rgb && (!m_scanparam->multi_output_red)) - m_scanparam->en_multi_output = mech; - else - return badValue(); - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->en_multi_output, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->en_multi_output, FALSE, m_scanparam->en_multi_output ? 1 : 0, 0); - }; - - // - m_query[(CapType)(CapTypeEx::TwEx_IEnMultiOutPutType)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IEnMultiOutPutType)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnMultiOutPutType), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype == (BYTE)PixelType::Rgb && (!m_scanparam->multi_output_red) && m_scanparam->en_multi_output) - m_scanparam->multioutput = mech; - else - return badValue(); - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->multioutput, 0); - }; - - //⿨ - m_query[(CapType)(CapTypeEx::TwEx_HsvCorrect)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_HsvCorrect)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_HsvCorrect), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech){ - if (m_scanparam->pixtype != (int)PixelType::Rgb) - return badValue(); - } - - m_scanparam->hsvcorrect = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->hsvcorrect, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->hsvcorrect, FALSE, m_scanparam->hsvcorrect ? 1 : 0, 0); - }; - - m_query[CapType::IFilter] = msgSupportGetAllSetReset; - m_caps[CapType::IFilter] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IFilter), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech == Filter::None || mech == Filter::Red || mech == Filter::Green || mech == Filter::Blue) { - if (((Filter)mech != Filter::None) && (m_scanparam->pixtype == (int)PixelType::Rgb)) - return badValue(); - m_scanparam->filter = (BYTE)mech; - if (mech != Filter::None) { - m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None; - } - return success(); - } - return badValue(); - } - return CapSupGetAllReset(msg, data, { Filter::Red,Filter::Green,Filter::Blue,Filter::None }, m_scanparam->filter, Filter::None, m_scanparam->filter, 3); - }; - - //ɫǿ - m_query[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnhanceColor), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype == (int)PixelType::Rgb) - { - m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None; - m_scanparam->filter = (BYTE)Filter::None; - return badValue(); - } - else - { - if (mech == Enchace_Color::Enhance_None || mech == Enchace_Color::Enhance_Red || mech == Enchace_Color::Enhance_Green || mech == Enchace_Color::Enhance_Blue) - { - m_scanparam->enhance_color = (BYTE)mech; - if (mech != (BYTE)Enchace_Color::Enhance_None) - m_scanparam->filter = (BYTE)Filter::None; - return success(); - } - } - } - return CapSupGetAllResetEx(msg, data, m_scanparam->enhance_color, (Enchace_Color)0); - //return CapSupGetAllResetEx(msg, data, { Enchace_Color::Enhance_None,Enchace_Color::Enhance_Red,Enchace_Color::Enhance_Green,Enchace_Color::Enhance_Blue }, m_scanparam->enhance_color, Enchace_Color::Enhance_None, m_scanparam->enhance_color, 0); - }; - - m_query[(CapType)(CapTypeEx::TwEx_Sharpen)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_Sharpen)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_Sharpen), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype == (int)PixelType::BlackWhite) - return badValue(); - m_scanparam->sharpen = (BYTE)mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->sharpen, SharpenBlur::Sharpen_None); - //return CapSupGetAllResetEx(msg, data, { SharpenBlur::Sharpen_None,SharpenBlur::Sharpen_Normal,SharpenBlur::Sharpen_More,SharpenBlur::Sharpen_Blur,SharpenBlur::Sharpen_Blur_More }, m_scanparam->sharpen, SharpenBlur::Sharpen_None, m_scanparam->sharpen, 0); - }; - - /* Աȶ gamma range Range */ - m_query[CapType::IBrightness] = msgSupportGetAllSetReset; - m_caps[CapType::IBrightness] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IBrightness), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - switch (msg) { - case Msg::Get: - data = Capability::createRange(Fix32(-1000.0f), Fix32(1000.0f), Fix32(333.3f), Fix32(m_scanparam->brightness), Fix32(0.0)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(m_scanparam->brightness)); - return success(); - case Msg::GetDefault: - case Msg::Reset: - m_scanparam->brightness = 0.0f; - data = Capability::createOneValue(Fix32(0.0f)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > 1000.0f || mech < -1000.0f) - return badValue(); - m_scanparam->brightness = (float)mech; - return success(); - } - default: - return capBadOperation(); - } - }; - - m_query[CapType::IContrast] = msgSupportGetAllSetReset; - m_caps[CapType::IContrast] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IContrast), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - switch (msg) { - case Msg::Get: - data = Capability::createRange(Fix32(-1000.0f), Fix32(1000.0f), Fix32(333.3f), Fix32(m_scanparam->contrast), Fix32(0.0)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(m_scanparam->contrast)); - return success(); - case Msg::GetDefault: - case Msg::Reset: - m_scanparam->contrast = 0.0f; - data = Capability::createOneValue(Fix32(0.0f)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > 1000.0f || mech < -1000.0f) - return badValue(); - m_scanparam->contrast = (float)mech; - return success(); - } - default: - return capBadOperation(); - } - }; - - m_query[CapType::IGamma] = msgSupportGetAllSetReset; - m_caps[CapType::IGamma] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::IGamma), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - switch (msg) { - case Msg::Get: - data = Capability::createRange(Fix32(0.0f), Fix32(5.0f), Fix32(1.0f), Fix32(m_scanparam->gamma), Fix32(1.0)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(m_scanparam->gamma)); - return success(); - case Msg::GetDefault: - case Msg::Reset: - m_scanparam->gamma = 1.0f; - data = Capability::createOneValue(Fix32(0.0f)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > 5.0f || mech < 0.0f) - return badValue(); - m_scanparam->gamma = (float)mech; - return success(); - } - default: - return capBadOperation(); - } - }; - - /*ΪӲЭ*/ - m_query[(CapType)(CapTypeEx::TwEx_ScrewDetectEnable)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_ScrewDetectEnable)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ScrewDetectEnable), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.en_skrewdetect = mech; - return success(); - } - Bool en = m_scanparam->hardwarecaps.en_skrewdetect == 0 ? Bool(false) : Bool(true); - return CapSupGetAllResetEx(msg, data,(Bool)m_scanparam->hardwarecaps.en_skrewdetect , Bool(true)); - //return CapSupGetAllResetEx(msg, data, { FALSE ,TRUE }, m_scanparam->hardwarecaps.en_skrewdetect, TRUE, m_scanparam->hardwarecaps.en_skrewdetect ? 1 : 0, 1); - }; - - m_query[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ScrewLevel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech >= 1 && mech <= 5) { - m_scanparam->hardwarecaps.skrewdetectlevel = mech; - return success(); - } - return badValue(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->hardwarecaps.skrewdetectlevel, (UInt32)3); - //return oneValGetSet(msg,data,m_scanparam->hardwarecaps.skrewdetectlevel,3); - }; - //װ - m_query[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_StableDetectEnable), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.en_stapledetect = mech; - - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->hardwarecaps.en_stapledetect, false); - //return CapSupGetAllResetEx(msg, data, { FALSE,TRUE }, m_scanparam->hardwarecaps.en_stapledetect, FALSE, m_scanparam->hardwarecaps.en_stapledetect==0 ? 0 : 1, 0); - }; - //۽Ǽ - m_query[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_DogEarDelection), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->is_dogeardetection = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_dogeardetection, FALSE); - }; - //۽Ǽ۶㵽ʵС - m_query[(CapType)(CapTypeEx::TwEx_DogEarDistance)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_DogEarDistance)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_DogEarDistance), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech >= 10 && mech <= 300) - m_scanparam->dogeardistance = mech; - else - return badValue(); - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->dogeardistance, 70); - }; - - //˫ż ٷ׼ Э޸Ϊbool Уʹboolͣʹñ׼twainЭ - m_query[CapType::DoubleFeedDetection] = msgSupportGetAllSetReset; - m_caps[CapType::DoubleFeedDetection] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapType::DoubleFeedDetection), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(CapType::DoubleFeedDetection, { 0 ,1}, m_scanparam->hardwarecaps.en_doublefeed ? 0 : 1, 0); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue(CapType::DoubleFeedDetection, (UInt16)m_scanparam->hardwarecaps.en_doublefeed ? 0 : 1); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - m_scanparam->hardwarecaps.en_doublefeed = 1; - data = Capability::createOneValue(CapType::DoubleFeedDetection, 0); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Set: { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.en_doublefeed = mech ? 0 : 1; - return success(); - } - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } - //if (Msg::Set == msg) { - // auto mech = data.currentItem(); - // m_scanparam->hardwarecaps.en_doublefeed = mech ? 1 : 0; - // return success(); - //} - //return CapSupGetAllResetEx(msg, data, m_scanparam->hardwarecaps.en_doublefeed, TRUE); - }; - -#ifdef G200 - //͹ģʽ - m_query[(CapType)(CapTypeEx::TwEx_LowPowerMode)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_LowPowerMode)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_LowPowerMode), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.lowpowermode = (LowPowerMode)mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->hardwarecaps.lowpowermode, LowPowerMode::Min_30); - //return CapSupGetAllResetEx(msg, data, - // { LowPowerMode::Min_None,LowPowerMode::Min_5,LowPowerMode::Min_10,LowPowerMode::Min_20, LowPowerMode::Min_30, LowPowerMode::Min_60, LowPowerMode::Min_120, LowPowerMode::Min_240 }, - // m_scanparam->hardwarecaps.lowpowermode, LowPowerMode::Min_30, (BYTE)m_scanparam->hardwarecaps.lowpowermode, 4); - }; - //ֽɨ - m_query[(CapType)(CapTypeEx::TwEx_IToBeScan)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IToBeScan)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IToBeScan), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.is_autopaper = mech; - if (mech) - m_scanparam->scannum = -1; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->hardwarecaps.is_autopaper, FALSE); - }; - -#endif // LANXUM - - m_query[(CapType)(CapTypeEx::TwEx_CropModel)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_CropModel)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropModel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->fillbackground || - m_scanparam->autodescrew || - m_scanparam->is_autocrop || - m_scanparam->en_fold) - { - return badValue(); - } - m_scanparam->normalCrop = (bool)mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->normalCrop, false); - }; - //ͼ - m_query[(CapType)(CapTypeEx::TwEx_ImageSplit)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_ImageSplit)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropModel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_scanparam->is_split = mech; - return success(); - } - return CapSupGetAllResetEx(msg, data, m_scanparam->is_split, false); - }; - - m_query[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = [this](Msg msg, Capability& data)->Result { - //CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropModel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (m_scanparam->pixtype != 2)//color - return badValue(); - - m_scanparam->hsvFilter = mech?1:0; - return success(); - } - bool hsv_v=(bool)(m_scanparam->hsvFilter); - return CapSupGetAllResetEx(msg, data, hsv_v, false); - }; -#ifdef UV - m_query[(CapType)(CapTypeEx::TwEx_UVModel)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::TwEx_UVModel)] = [this](Msg msg, Capability& data)->Result { - CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_UVModel), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); - switch (msg) { - case Msg::Get:{ - data = Capability::createOneValue((CapType)(CapTypeEx::TwEx_UVModel), Bool(m_scanparam->hardwarecaps.en_uv)); - //data = Capability::createEnumeration((CapType)(CapTypeEx::TwEx_UVModel), { Bool(),Bool(true) }, Bool(m_scanparam->hardwarecaps.en_uv), 0); - return success(); - } - case Msg::Reset: - m_scanparam->hardwarecaps.en_uv = false; - case Msg::GetCurrent: - data = Capability::createOneValue((CapType)(CapTypeEx::TwEx_UVModel), m_scanparam->hardwarecaps.en_uv); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue((CapType)(CapTypeEx::TwEx_UVModel), Bool(false)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - m_scanparam->hardwarecaps.en_uv = mech?1:0; - return success(); - } - default: - return capBadOperation(); - } - }; -#endif - - return success(); -} - -Result HuagaoDs::identityCloseDs(const Identity&) { - // no need to explicitly release any resources if using RAII - // TWPP will free the whole source on its own after this method - if (guiIndicator->GetSafeHwnd()) - guiIndicator->DestroyWindow(); - - if (guiTwain.get()) - guiTwain.reset(); - - if (guiBridge.get()) - guiBridge.reset(); - - scanner.reset(); - bmpData.reset(); - if (hMutex) - { - ReleaseMutex(hMutex); - CloseHandle(hMutex); - } - //saveGscanCapSetting(); - return success(); -} - -Result HuagaoDs::pendingXfersGet(const Identity&, PendingXfers& data) { - data.setCount(m_pendingXfers); - return success(); -} - -Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) { - //!< end xfer if set count 0 - if (bmpData->size() > 0) - { - bmpData.reset(new std::vector); - } - - int ret = scanner->aquire_bmpdata(*bmpData.get()); - - if (ret != 0) { - scanner->Set_ErrorCode(0); - if (guiIndicator->GetSafeHwnd()) - guiIndicator->ShowWindow(SW_HIDE); - if (ret != -1) { - int index = scanner->geterrorindex(); - if (ret == 82 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", ret); - else if (ret == 75 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", ret); - else if (ret == 81 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "豸ģʽֶ豸", ret); - else - showmsg("ʾ", msgs[(UsbSupported)ret], ret); - FileTools::writelog(log_ERROR, msgs[(UsbSupported)ret]); -#ifndef G200 - scanner->clear_hwerror(); -#endif // G200 - } - else - { - if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince)) - { - int num = scanner->get_scannum() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1) * (m_scanparam->is_split ? 2 : 1) - * (m_scanparam->en_multi_output ? (m_scanparam->multioutput < 0 ? 1 : (m_scanparam->multioutput == 0 ? 3 : 2)) : 1); - if ((num - scanner->get_imgTransfered()) != 0) - { - showmsg("ʾ", msgs[LOSE_IMAGE]); - FileTools::writelog(log_ERROR, msgs[LOSE_IMAGE]); - } - - } - } - m_pendingXfers = 0; - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true); - //setState(DsState::Enabled); - } - else { - //setState(DsState::Open); - } - } - else { - m_pendingXfers = 1; - //setState( DsState::XferReady ); - } - data.setCount(m_pendingXfers); - return success(); -} - -Result HuagaoDs::pendingXfersReset(const Identity&, PendingXfers& data) { - data.setCount(0); - if (scanner.get()) - { - scanner->Stop_scan(); - //scanner->reset(); - scanner->ResetScanner(); - } - //guiIndicator.reset(); - if (guiIndicator->GetSafeHwnd()) - guiIndicator->DestroyWindow(); - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true); - } - return success(); -} - -Result HuagaoDs::setupMemXferGet(const Identity&, SetupMemXfer& data) { - auto bpl = bytesPerLine(); - auto max = bpl * static_cast(header()->biHeight); - - data.setMinSize(bpl); - data.setPreferredSize(max); - data.setMaxSize(max); - return success(); -} - -Result HuagaoDs::userInterfaceDisable(const Identity&, UserInterface& ui) { - if (guiTwain.get()) - guiTwain.reset(); - -#if TWPP_DETAIL_OS_WIN - if (guiBridge.get()) - guiBridge.reset(); -#endif - - return success(); -} - -Result HuagaoDs::userInterfaceEnable(const Identity&, UserInterface& ui) { - m_pendingXfers = 1; - m_memXferYOff = 0; - - if (!ui.showUi()) { - // this is an exception when we want to set state explicitly, notifyXferReady can be called only in enabled state - // with hidden UI, the usual workflow DsState::Enabled -> notifyXferReady() -> DsState::XferReady is a single step - - - if (!scanner->IsConnected()) - scanner->open(vid, pid); - if (!scanner->IsConnected()) - { - MessageBox(NULL, L"USB쳣,USB´ɨ", L"ʾ", MB_OK | MB_SYSTEMMODAL); - return seqError(); - } -#ifndef G200 - if (typeid(*scanner.get()) != typeid(GScanO1003399)) { - while (!scanner->Get_Scanner_PaperOn()) - { - if (MessageBox(NULL, L"⵽ֽֽ", L"ʾ", MB_YESNO | MB_SYSTEMMODAL) == IDNO) - return seqError(); - } - } -#endif // !G200 - this_thread::sleep_for(chrono::milliseconds(100)); //ɨǰӳ ֹusbеϢδȡ ɨ - auto ret = startScan(); - //if (ret.status().condition() == Twpp::CC::NoMedia) - // return ret; - if (ret == success()) { - m_pendingXfers = 1; - } - else { - m_pendingXfers = 0; - return seqError(); - } - return success(); - } - return showTwainUI(ui); -} - -Result HuagaoDs::userInterfaceEnableUiOnly(const Identity&, UserInterface& ui) { - // as a minimal source, we do not support GUI that just saves settings - return showTwainUI(ui, true); -} - -Result HuagaoDs::imageInfoGet(const Identity&, ImageInfo& data) { - // our image does not change - //if (m_pendingXfers == 0 || bmpData->size() == 0) - if(bmpData->size() == 0) - return success(); - auto dib = header(); - data.setBitsPerPixel(static_cast(dib->biBitCount)); - data.setHeight(dib->biHeight); - data.setPixelType(dib->biClrUsed == 2 ? PixelType::BlackWhite : (dib->biClrUsed == 256 ? PixelType::Gray : PixelType::Rgb)); - data.setPlanar(false); - data.setWidth(dib->biWidth); - data.setXResolution(m_scanparam->resolution_dst); - data.setYResolution(m_scanparam->resolution_dst); - data.compression(m_compression); - switch (dib->biClrUsed) - { - case 2: - case 256: - data.setSamplesPerPixel(1); - data.bitsPerSample()[0] = 8; - break; - case 0: - data.setSamplesPerPixel(3); - data.bitsPerSample()[0] = 8; - data.bitsPerSample()[1] = 8; - data.bitsPerSample()[2] = 8; - default: - break; - } - return success(); -} - -Result HuagaoDs::imageLayoutGet(const Identity&, ImageLayout& data) { - // our image does not change - auto dib = header(); - - data.setDocumentNumber(1); - data.setFrameNumber(1); - data.setPageNumber(1); - data.setFrame(Frame(0, 0, static_cast(dib->biWidth) / m_scanparam->resolution_dst, static_cast(dib->biHeight) / m_scanparam->resolution_dst)); - return success(); -} - -Result HuagaoDs::imageLayoutGetDefault(const Identity& origin, ImageLayout& data) { - return imageLayoutGet(origin, data); -} - -Result HuagaoDs::imageLayoutSet(const Identity& origin, ImageLayout& lay) { - // we dont support setting image frame - - ImageLayout def; - imageLayoutGetDefault(origin, def); - - return lay.frame() == def.frame() ? success() : badValue(); -} - -Result HuagaoDs::imageLayoutReset(const Identity& origin, ImageLayout& data) { - return imageLayoutGet(origin, data); -} - -Result HuagaoDs::imageMemXferGet(const Identity& origin, ImageMemXfer& data) { - if (!m_pendingXfers) { - return seqError(); - } - - // we can call our TWPP methods, but be careful about states - SetupMemXfer setup; - setupMemXferGet(origin, setup); - - // just a simple stored BMP image - auto dib = header(); - auto bpl = bytesPerLine(); - auto memSize = data.memory().size(); - if (memSize > setup.maxSize() || memSize < setup.minSize()) { - return badValue(); - } - - auto maxRows = memSize / bpl; - auto rows = std::min(maxRows, static_cast(dib->biHeight) - m_memXferYOff); - if (rows == 0) { - return seqError(); // image already transfered in this session - } - cv::Mat mat; - vector cmpdata; - if (m_compression == Compression::Group4) - { - mat = cv::imdecode(*bmpData.get(), cv::IMREAD_GRAYSCALE); - G4Tiff gt(mat, G4Tiff::Mode::MemoryMode, "", 120, m_scanparam->resolution_dst); - gt.GetCompressedData(cmpdata); - } - - data.setBytesPerRow(bpl); - data.setColumns(static_cast(dib->biWidth)); - data.setRows(rows); - data.setBytesWritten(m_compression == Compression::None ? bpl * rows : cmpdata.size()); - data.setXOffset(0); - data.setYOffset(m_memXferYOff); - data.setCompression(m_compression); - - auto lock = data.memory().data(); - char* out = lock.data(); - - auto bmpsize = bmpData->size(); - // bottom-up BMP -> top-down memory transfer - if (m_compression == Compression::None) - { - auto begin = bmpEnd() - (bpl * (m_memXferYOff + 1)); - for (UInt32 i = 0; i < rows; i++) { - // copy bytes - std::copy(begin, begin + bpl, out); - - char* line = out; - out += bpl; - begin -= bpl; - if (dib->biBitCount == 24) - { - //BGR BMP -> RGB memory transfer - for (; line + 3 < out; line += 3) { - std::swap(line[0], line[2]); - } - } - } - } - else - { - std::copy(cmpdata.data(), cmpdata.data() + cmpdata.size(), out); - } - - m_memXferYOff += rows; - - if (m_memXferYOff >= static_cast(std::abs(dib->biHeight))) { - m_pendingXfers = 0; - m_memXferYOff = 0; - //bmpData.reset(new std::vector); - return { ReturnCode::XferDone, ConditionCode::Success }; - } - - return success(); -} - -static int xtfer = 0; -Result HuagaoDs::imageNativeXferGet(const Identity& id, ImageNativeXfer& data) { - if (!m_pendingXfers) { - return seqError(); - } - if (m_haveError) - return { ReturnCode::Cancel, ConditionCode::Success }; - if (data) - data.release(); - // it does not get easier than that if we already have BMP - data = ImageNativeXfer(bmpSize()); - std::copy(bmpBegin(), bmpEnd(), data.data().data()); - //bmpData.reset(new std::vector); - //FileTools::write_log("ϴͼƬ ===> Twain transfered num of " + to_string(++xtfer) + " images"); - FileTools::writelog(log_INFO, "ϴͼƬ ===> Twain transfered num of " + to_string(++xtfer) + " images"); - return { ReturnCode::XferDone, ConditionCode::Success }; -} - -Twpp::Result HuagaoDs::pendingXfersStopFeeder(const Identity& origin, PendingXfers& data) -{ - if (!scanner.get()) - return seqError(); - if (scanner->IsConnected()) { - scanner->Stop_scan(); - } - data.setCount(scanner->Get_IsImageQueueEmpty() ? 0 : 1); - return success(); -} - -Twpp::Result HuagaoDs::setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - data.setFilePath(m_fileXfer.filePath()); - data.setFormat(m_fileXfer.format()); - return success(); -} - -Twpp::Result HuagaoDs::setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - Str255 str("HGTwain.bmp"); - data.setFilePath(str); - data.setFormat(ImageFileFormat::Bmp); - return success(); -} - -Twpp::Result HuagaoDs::setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - m_fileXfer.setFilePath(data.filePath()); - m_fileXfer.setFormat(data.format()); - return success(); -} - -Twpp::Result HuagaoDs::setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - m_fileXfer.setFormat(Twpp::ImageFileFormat::Bmp); - std::string templateName = "HG"; - char* tempPath = mktemp((char*)templateName.c_str()); - if (tempPath) { - Str255 str; - str.setData(tempPath, strlen(tempPath)); - m_fileXfer.setFilePath(str); - return success(); - } - return badProtocol(); -} - -static int indeximg = 0; - -Twpp::Result HuagaoDs::imageFileXferGet(const Twpp::Identity& origin) -{ - if (!m_pendingXfers) - return seqError(); - string filename = m_fileXfer.filePath().string(); - switch (m_fileXfer.format()) - { - case ImageFileFormat::Bmp: { - - FILE* pfile = fopen(filename.c_str(), "wb"); - if (pfile) { - if (bmpData->size() > 0) { - fwrite(bmpData->data(), 1, bmpData->size(), pfile); - bmpData.reset(new std::vector); - fclose(pfile); - return Result(ReturnCode::XferDone, ConditionCode::Success); - } - } - return Result(ReturnCode::Failure, ConditionCode::BadValue); - } - case ImageFileFormat::Tiff: - case ImageFileFormat::Jfif: { - - BITMAPINFOHEADER& bmpinfo = *((BITMAPINFOHEADER*)header()); - int decodetype; - if (bmpinfo.biBitCount == 24) - decodetype = cv::IMREAD_COLOR; - else - decodetype = cv::IMREAD_GRAYSCALE; - - - cv::Mat ims = cv::imdecode(*bmpData.get(), decodetype); - - if (m_compression == Compression::Group4 && m_fileXfer.format() == ImageFileFormat::Tiff) - { - if (!ims.empty() && ims.channels() == 3) - cvtColor(ims, ims, cv::COLOR_BGR2GRAY); - G4Tiff gsave(ims, G4Tiff::Mode::FileMode, filename, 120, m_scanparam->resolution_dst); - gsave.SaveG4Tiff(); - } - else - { - std::vector compression_params; - compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); - compression_params.push_back(m_jpegQuality); - std::vector imgdate; - cv::imencode(".jpg", ims, imgdate, compression_params); - std::ofstream out(filename,std::ios::binary | std::ios::out | std::ios::trunc); - if (out.is_open()) - out.write((const char*)imgdate.data(), imgdate.size()),out.close(); - //cv::imwrite(filename, ims, compression_params); - } - bmpData.reset(new std::vector); - ims.release(); - return Result(ReturnCode::XferDone, ConditionCode::Success); - } - default: - break; - } - return badProtocol(); -} - -Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly) -{ - // as a minimal source, we do not support GUI that just saves settings - if (ui.parent()) { - guiBridge.reset(new CDialog()); - HWND appWindow = static_cast(ui.parent().raw()); - guiBridge->Create(IDD_BACK, CWnd::FromHandle(appWindow)); - HWND bridgeWindow = guiBridge->GetSafeHwnd(); - long bridgeFlags = GetWindowLong(bridgeWindow, GWL_STYLE); - SetWindowLong(bridgeWindow, GWL_STYLE, bridgeFlags | WS_CHILD); - SetParent(bridgeWindow, appWindow); - } - - //!< show ui to scan button push - auto scanFunction = [this](const GScanCap& caps) { - if (!scanner->IsConnected()) - { - scanner->open(vid, pid); - if (!scanner->IsConnected()) - return checkDeviceOnline(); - } - -#ifndef G200 - if (typeid(*scanner.get()) != typeid(GScanO1003399)) { - while (!scanner->Get_Scanner_PaperOn()) - { - if (MessageBox(NULL, L"⵽ֽֽ", L"ʾ", MB_YESNO | MB_SYSTEMMODAL) == IDNO) { - m_pendingXfers = 0; - return seqError(); - } - } - } -#endif // !G200 - m_pendingXfers = 1; - m_scanparam.reset(new GScanCap(caps)); - saveGscanCapSetting(); - if (!scanner->IsConnected()) - { - MessageBox(NULL, L"USB쳣,USB´ɨ", L"ʾ", MB_OK | MB_SYSTEMMODAL); - return seqError(); - } - - if (startScan() == success()) { - notifyXferReady(); - } - else { - m_pendingXfers = 0; - } - }; - - //!< ui only to confirm button push - auto confirmFunction = [this](const GScanCap& caps) { - m_scanparam.reset(new GScanCap(caps)); - saveGscanCapSetting(); - notifyCloseOk(); - }; - - //!< cancel button push - auto cancelFunction = [this]() { - //if (m_modal) - //{ - // ::EnableWindow(parent, true); - //} - notifyCloseCancel(); - }; - - CWnd* parent = guiBridge.get(); - - TwGlue glue = { scanFunction, cancelFunction }; - TwGlue glueUiOnly = { confirmFunction, cancelFunction }; - std::string serialnum = scanner->GetSerialNum(); - std::string hardwareversion = scanner->GetFWVersion(); - std::string macadder = scanner->GetMacAdder(); - uint32_t mbversion = scanner->GetMotorFPGA(); - guiTwain.reset(new CTwainUI(bUiOnly ? glueUiOnly : glue, *m_scanparam, bUiOnly ? "ȷ" : "ɨ", hardwareversion, serialnum,macadder,mbversion)); - guiTwain->Create(IDD_TWAINUI, parent); - CRect newRect; - ::GetWindowRect(static_cast(ui.parent().raw()), &newRect); - if (newRect.top <= 0 || newRect.left <= 0) - newRect.top = newRect.left = 20; - SetWindowPos(guiTwain->m_hWnd, HWND_TOP, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE); - //SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); - guiTwain->ShowWindow(SW_SHOWNORMAL); - return success(); -} - -void HuagaoDs::DeviceEvent_callback(int eventID, void* usrdata) -{ - HuagaoDs* This = (HuagaoDs*)usrdata; - This->onDeviceEvent(eventID); -} - -void HuagaoDs::CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value) -{ - if (!is_printfcapability) - return; - switch (msg) - { - case Msg::Reset: - FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Reset) + "\t" + capability); - break; - case Msg::Get: - FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Get) + "\t" + capability); - break; - case Msg::GetCurrent: - FileTools::writelog(log_INFO, (std::string)enum2str(Msg::GetCurrent) + "\t" + capability); - break; - case Msg::GetDefault: - FileTools::writelog(log_INFO, (std::string)enum2str(Msg::GetDefault) + "\t" + capability); - break; - case Msg::Set: - FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Set) + "\t" + capability+"\t value = "+value); - break; - default: - break; - } -} - -void HuagaoDs::onDeviceEvent(int eventID) -{ - //if (mapDeviceEvent.count(eventID)) - //{ - // DeviceEvent::Type dev_type = mapDeviceEvent[eventID]; - // auto evt = DeviceEvent::simple((DeviceEvent::Type)dev_type, "HuaGo Device Event"); - // devEvent.push(evt); - // notifyDeviceEvent(); - //} -} - -const BITMAPINFOHEADER* HuagaoDs::header() const noexcept { - return reinterpret_cast(bmpData->data() + sizeof(BITMAPFILEHEADER)); -} - -UInt32 HuagaoDs::bytesPerLine() const noexcept { - auto dib = header(); - return static_cast(dib->biWidth * dib->biBitCount + 31) / 32 * 4; -} - -UInt32 HuagaoDs::bmpSize() const noexcept { - return static_cast(bmpData->size()) - sizeof(BITMAPFILEHEADER); -} - -const char* HuagaoDs::bmpBegin() const noexcept { - return (const char*)bmpData->cbegin()._Ptr + sizeof(BITMAPFILEHEADER); -} - -const char* HuagaoDs::bmpEnd() const noexcept { - return (const char*)bmpData->cend()._Ptr; -} - -void HuagaoDs::updataGscanCap() -{ - GscanJsonConfig js; - GScanCap cfs = js.ReadGscanCap(); - cfs.resolution_native = 200.0f; - cfs.threshold = 128; - if (cfs.is_autocrop) - { - m_autoboarderdetcet = true; - m_autosize = (UInt16)AutoSize::Auto; - } - - m_scanparam.reset(new GScanCap(cfs)); -} - -Twpp::Result HuagaoDs::startScan() -{ - xtfer = 0; - //if (!scanner->IsConnected()) - //{ - // scanner->open(vid, pid); - // if (!scanner->IsConnected()) - // return checkDeviceOnline(); - //} - bmpData.reset(new std::vector()); - scanner->ResetScanner(); - scanner->reset(); - FileTools::writelog(log_INFO, "start scan"); - -#ifdef G200 - scanner->clear_hwerror(); -#else -#ifndef ANDROIDSERIAL - if (scanner->notifyscan() < 1) - return seqError(); -#endif // !ANDROIDSERIAL -#endif // - -#ifdef G200 - if (scanner->Get_Roller_num() > 450000) -#elif defined G300 - if (scanner->Get_Roller_num() > 150000) -#else - if (scanner->Get_Roller_num() > 200000) -#endif // G200 - { - Twain_config config; - if (config.getrollermsgdate() < chrono::duration_cast>>(chrono::system_clock::now().time_since_epoch()).count()){ - hgmsg(_T("ִֽֽѳʹ÷Χɨдֽʧܡбŵ쳣Ƶοܻ࣬ע⼰ʱࡢϵ豸Ӧ̹滻ֽ֣")); - config.setrollermsgdata(chrono::duration_cast>>(chrono::system_clock::now().time_since_epoch()).count()); - } - } - //m_scanparam->brightness =300; // һ 500 - 142 - //m_scanparam->contrast = 0; // Сר - scanner->config_params(*m_scanparam); - std::string info = "papertype= " + to_string(m_scanparam->papertype) + - "\nAutoCrop_threshold= " + to_string(m_scanparam->AutoCrop_threshold) + - "\nautodescrew = " + to_string(m_scanparam->autodescrew) + - "\nautomaticcolor= " + to_string(m_scanparam->automaticcolor) + - "\nbrightness = " + to_string(m_scanparam->brightness) + - "\ncontrast = " + to_string(m_scanparam->contrast) + - "\nis_detachnoise = " + to_string(m_scanparam->detachnoise.is_detachnoise) + - "\ndetachnoise = " + to_string(m_scanparam->detachnoise.detachnoise) + - "\nen_fold = " + to_string(m_scanparam->en_fold) + - "\nen_sizecheck = " + to_string(m_scanparam->en_sizecheck) + - "\nenhance_color = " + to_string(m_scanparam->enhance_color) + - "\nfillbackground = " + to_string(m_scanparam->fillbackground) + - "\nfilter = " + to_string(m_scanparam->filter) + - "\nis_fillhole = " + to_string(m_scanparam->fillhole.is_fillhole) + - "\ngamma = " + to_string(m_scanparam->gamma) + - "\ncapturepixtype = " + to_string(m_scanparam->hardwarecaps.capturepixtype) + - "\nen_doublefeed = " + to_string(m_scanparam->hardwarecaps.en_doublefeed) + - "\nhsvcorrect = " + to_string(m_scanparam->hsvcorrect) + - "\nimageRotateDegree = " + to_string(m_scanparam->imageRotateDegree) + - "\nindent = " + to_string(m_scanparam->indent) + - "\nis_autocontrast = " + to_string(m_scanparam->is_autocontrast) + - "\nis_autocrop = " + to_string(m_scanparam->is_autocrop) + - "\nis_autocontrast = " + to_string(m_scanparam->is_autocontrast) + - "\nis_autodiscradblank_normal = " + to_string(m_scanparam->is_autodiscradblank_normal) + - "\nis_autodiscradblank_vince = " + to_string(m_scanparam->is_autodiscradblank_vince) + - "\nis_autotext = " + to_string(m_scanparam->is_autotext) + - "\nis_convex = " + to_string(m_scanparam->is_convex) + - "\nis_duplex = " + to_string(m_scanparam->is_duplex) + - "\nis_switchfrontback = " + to_string(m_scanparam->is_switchfrontback) + - "\nis_dogeardetection = " + to_string(m_scanparam->is_dogeardetection) + - "\nmulti_output_red = " + to_string(m_scanparam->multi_output_red) + - "\nen_multi_output = " + to_string(m_scanparam->en_multi_output) + - "\nmultioutput = " + to_string(m_scanparam->multioutput) + - "\nnoise = " + to_string(m_scanparam->noise) + - "\npaperAlign = " + to_string(m_scanparam->paperAlign) + - "\npixtype = " + to_string(m_scanparam->pixtype) + - "\nresolution_dst = " + to_string(m_scanparam->resolution_dst) + - "\nscannum = " + to_string(m_scanparam->scannum) + - "\nsharpen = " + to_string(m_scanparam->sharpen); - FileTools::writelog(log_TRACE,info); - - scanner->UpdateScanInfo(0, 0); - scanner->Scanner_StartScan(m_scanparam->scannum); - if (bmpData->size() > 0) - { - bmpData.reset(new std::vector); - } - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(false); - } - int retCode = scanner->aquire_bmpdata(*bmpData.get()); - if (retCode == 0) - { - if (m_bIndicator) { - //!< cancel button push - auto stopFunc = [this]() { - if (scanner.get()) - scanner->Stop_scan(); - //guiIndicator.reset();//ȡɨ رսָʾ - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true); - } - onDeviceEvent(USER_STOP); - }; - guiIndicator = new CIndicatorDlg(stopFunc); - scanner->regist_indicatortext_callback([this](int aquire, int updata) - { if (guiIndicator->GetSafeHwnd()) - guiIndicator->setindicatortext(aquire, updata); - }); - guiIndicator->Create(IDD_INDICATOR, guiTwain.get() ? guiTwain.get() : guiBridge.get());//guiTwain ? guiTwain.get() : guiBridge.get() - guiIndicator->ShowWindow(SW_SHOWNORMAL); - } - } - if (retCode != 0) { - scanner->Set_ErrorCode(0); - if (guiIndicator->GetSafeHwnd()) - guiIndicator->DestroyWindow(); - - //if(guiIndicator.get()) - // guiIndicator.reset(); - if (retCode != -1) { - CString str; - str.Format(_T("%d"), retCode); - m_pendingXfers = 0; - m_memXferYOff = 0; - m_haveError = true; - //ShellExecute(guiTwain ? guiTwain->m_hWnd : NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE); - int index = scanner->geterrorindex(); - if (retCode == 82 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", retCode); - else if (retCode == 75 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", retCode); - else if (retCode == 81 && ((typeid(*scanner.get()) == typeid(GScanO1003399)))) - showmsg("ʾ", "豸ģʽֶ豸", retCode); - else - showmsg("ʾ", msgs[(UsbSupported)retCode], retCode); - FileTools::writelog(log_ERROR, msgs[(UsbSupported)retCode]); -#ifndef G200 - scanner->clear_hwerror(); -#endif // - } - - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true); - } - if (retCode == 2) - return { ReturnCode::Failure, ConditionCode::NoMedia };//ֽ - - return seqError(); - } - - if (bmpData->size() > 0) { - m_haveError = false; - return success(); - } - else { - if (guiTwain.get()) { - ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true); - } - return seqError(); - } -} - -void HuagaoDs::saveGscanCapSetting() -{ - TCHAR szIniFile[MAX_PATH] = { 0 }; - SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_LOCAL_APPDATA, TRUE); - _tcscat(szIniFile, HUAGAO_SCAN); - _tcscat(szIniFile, TWAIN_INIPATH); - _tcscat(szIniFile, TEXT("\\")); - _tcscat(szIniFile, TWAIN_JSON_NAME); - GscanJsonConfig js; - //vector vc; - //vc.push_back(*m_scanparam); - std::string savepath = TCHAR2STRING(szIniFile); - js.SaveGscancapJson(*m_scanparam, savepath); - //js.WriteJsonArrayToFile(vc, savepath); -} +} \ No newline at end of file