From e7c4c666f61ec41eed42a8034a6d44c32f058701 Mon Sep 17 00:00:00 2001 From: masayume <1936714878@qq.com> Date: Sat, 20 Nov 2021 11:09:04 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4twain=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.txt | 11 + huagao/CAboutDlg.cpp | 8 +- huagao/CAdvancedDLG.cpp | 2 +- huagao/CAttributeDlg.cpp | 46 + huagao/CAttributeDlg.h | 25 + huagao/CBasicPage.cpp | 19 +- huagao/CBasicPage.h | 1 + huagao/CFeedPaperPage.cpp | 19 + huagao/CFeedPaperPage.h | 3 + huagao/CTwainUI.cpp | 22 +- huagao/CTwainUI.h | 1 + huagao/Device/G400ScanConfig.cpp | 34 + huagao/Device/G400ScanConfig.h | 29 + huagao/Device/GScan.h | 26 +- huagao/Device/GScanO1003399.cpp | 52 +- huagao/Device/GScanO1003399.h | 1 + huagao/Device/GScanO200.cpp | 2 +- huagao/Device/GScanO400.cpp | 69 +- huagao/Device/GScanO400.h | 2 +- huagao/Device/GScanO400Android.cpp | 810 ++++++++++++++++++ huagao/Device/GScanO400Android.h | 59 ++ huagao/Device/ImageMatQueue.cpp | 54 +- huagao/Device/ImageMatQueue.h | 18 +- huagao/Device/PaperSize.cpp | 4 + huagao/Device/PublicFunc.cpp | 2 + huagao/Device/PublicFunc.h | 7 + huagao/Device/UsbScanEx.cpp | 332 ++++++- huagao/Device/UsbScanEx.h | 2 +- huagao/Device/filetools.h | 1 + huagao/GscanJsonConfig.cpp | 108 ++- huagao/GscanJsonConfig.h | 18 + huagao/ImageProcess/ImageApplyAutoCrop.cpp | 68 +- huagao/ImageProcess/ImageApplyAutoCrop.h | 27 +- huagao/ImageProcess/ImageApplyBWBinaray.cpp | 1 + .../ImageApplyDogEarDetection.cpp | 87 +- .../ImageProcess/ImageApplyDogEarDetection.h | 10 +- huagao/ImageProcess/ImageApplyOutHole.cpp | 150 +++- huagao/ImageProcess/ImageApplyOutHole.h | 42 +- huagao/ImageProcess/ImageApplyUV.cpp | 2 - huagao/auge_logo.bmp | Bin 0 -> 162054 bytes huagao/auge_logo1111.bmp | Bin 0 -> 105894 bytes huagao/hanvon.bmp | Bin 0 -> 76790 bytes huagao/hanvon_log.bmp | Bin 0 -> 132294 bytes huagao/huagaods.cpp | 345 +++++--- huagao/huagaods.hpp | 4 +- huagao/huagaotwds.rc | Bin 43466 -> 48940 bytes huagao/resource.h | Bin 14286 -> 17502 bytes huagao/stdafx.h | Bin 15276 -> 18276 bytes 48 files changed, 2095 insertions(+), 428 deletions(-) create mode 100644 changelog.txt create mode 100644 huagao/CAttributeDlg.cpp create mode 100644 huagao/CAttributeDlg.h create mode 100644 huagao/Device/GScanO400Android.cpp create mode 100644 huagao/Device/GScanO400Android.h create mode 100644 huagao/auge_logo.bmp create mode 100644 huagao/auge_logo1111.bmp create mode 100644 huagao/hanvon.bmp create mode 100644 huagao/hanvon_log.bmp diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 00000000..3c7c29b3 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,11 @@ +2021年11月16日 + 版本:3.3.5.4 + 1.添加搓纸轮使用过多提示 + 2.修改扫描提示 + 3.修复保存首选项不能保存高级设置参数问题 + 4.新增奥鸽G139型号 +2021年11月20日 + 版本:3.3.5.4 + 1.添加配置文件,可开关显示滚轴弹框以及打印协议设置信息 + 2.调整twain协议 + 3.更新穿孔算法 \ No newline at end of file diff --git a/huagao/CAboutDlg.cpp b/huagao/CAboutDlg.cpp index d5ae3e82..0141d146 100644 --- a/huagao/CAboutDlg.cpp +++ b/huagao/CAboutDlg.cpp @@ -54,13 +54,15 @@ BOOL CAboutDlg::OnInitDialog() #ifdef MAKEHUAGAO HBITMAP hBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BMPABOUTDLG)); #elif defined HANVON - HBITMAP hBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP3)); -#else defined LANXUM + HBITMAP hBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1)); +#elif defined LANXUM HBITMAP hBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2)); +#elif defined AUGE + HBITMAP hBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP4)); #endif pStatic->ModifyStyle(0xF, SS_BITMAP | SS_CENTERIMAGE); pStatic->SetBitmap(hBitmap); -#if defined MAKEHUAGAO || defined LANXUM || defined HANVON +#if defined MAKEHUAGAO || defined LANXUM || defined HANVON || defined AUGE GetDlgItem(IDC_PICABOUTHUAGO)->ShowWindow(TRUE); #else GetDlgItem(IDC_PICABOUTHUAGO)->ShowWindow(FALSE); diff --git a/huagao/CAdvancedDLG.cpp b/huagao/CAdvancedDLG.cpp index b5218f7f..c94a1e28 100644 --- a/huagao/CAdvancedDLG.cpp +++ b/huagao/CAdvancedDLG.cpp @@ -42,7 +42,7 @@ BOOL CAdvancedDLG::OnInitDialog() CTabPageSSL::OnInitDialog(); m_Edit_noise.SetSlideLink(this, IDC_SLIDER_NOISE); - m_Edit_noise.SetParams(1, 10, 1); + m_Edit_noise.SetParams(1, 20, 1); m_Edit_noise.SetValue(noise); m_Edit_indent.SetSlideLink(this, IDC_SLIDER_INDENT); diff --git a/huagao/CAttributeDlg.cpp b/huagao/CAttributeDlg.cpp new file mode 100644 index 00000000..72d656f1 --- /dev/null +++ b/huagao/CAttributeDlg.cpp @@ -0,0 +1,46 @@ +// CAttributeDlg.cpp: 实现文件 +// + +#include "CAttributeDlg.h" + + +// CAttributeDlg 对话框 + +IMPLEMENT_DYNAMIC(CAttributeDlg, CDialogEx) + +CAttributeDlg::CAttributeDlg(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_ATTRIBUTE, pParent) +{ + +} + +CAttributeDlg::~CAttributeDlg() +{ +} + +BOOL CAttributeDlg::OnInitDialog() +{ + this->SetWindowTextW(L"扫描仪属性"); + return TRUE; +} + +void CAttributeDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + + +BEGIN_MESSAGE_MAP(CAttributeDlg, CDialogEx) + ON_BN_CLICKED(IDC_BTN_ATTOK, &CAttributeDlg::OnBnClickedBtnAttok) +END_MESSAGE_MAP() + + +// CAttributeDlg 消息处理程序 + + +void CAttributeDlg::OnBnClickedBtnAttok() +{ + CDialogEx::OnOK(); + // TODO: 在此添加控件通知处理程序代码 +} + diff --git a/huagao/CAttributeDlg.h b/huagao/CAttributeDlg.h new file mode 100644 index 00000000..ce0d89a0 --- /dev/null +++ b/huagao/CAttributeDlg.h @@ -0,0 +1,25 @@ +#pragma once +#include "stdafx.h" +#include "resource.h" +// CAttributeDlg 对话框 + +class CAttributeDlg : public CDialogEx +{ + DECLARE_DYNAMIC(CAttributeDlg) + +public: + CAttributeDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CAttributeDlg(); + +// 对话框数据 +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_ATTRIBUTE }; +#endif + virtual BOOL OnInitDialog(); +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedBtnAttok(); +}; diff --git a/huagao/CBasicPage.cpp b/huagao/CBasicPage.cpp index 379291d4..c2381540 100644 --- a/huagao/CBasicPage.cpp +++ b/huagao/CBasicPage.cpp @@ -6,6 +6,7 @@ #include "afxdialogex.h" #include "resource.h" #include "CAboutDlg.h" +#include "CAttributeDlg.h" #include "CTwainUI.h" #include "CDiscardBlankSetting.h" #include "CcardblankDlg.h" @@ -84,9 +85,11 @@ static std::vector surportStyles = { _T("Double Letter"),//pass _T("LEGAL"), _T("匹配原始尺寸"), +#ifndef ANDROIDSERIAL _T("最大扫描尺寸自动裁切"), _T("最大扫描尺寸"), _T("三联试卷"), +#endif // !ANDROIDSERIAL }; #endif // G400 @@ -170,6 +173,7 @@ BOOL CBasicPage::OnInitDialog() #ifndef UV GetDlgItem(IDC_CKBENABLEUV)->ShowWindow(FALSE); #endif + GetDlgItem(IDC_BTN_ATTRIBYTE)->ShowWindow(SW_HIDE); return true; } @@ -182,6 +186,7 @@ BEGIN_MESSAGE_MAP(CBasicPage, CTabPageSSL) ON_CBN_SELCHANGE(IDC_CMBDUPLEX, &CBasicPage::OnCbnSelchangeCmbduplex) ON_BN_CLICKED(IDC_BTNDISCARDSETTING, &CBasicPage::OnClickedBtndiscardsetting) ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDERDPI, &CBasicPage::OnNMReleasedcaptureSliderdpi) + ON_BN_CLICKED(IDC_BTN_ATTRIBYTE, &CBasicPage::OnBnClickedBtnAttribyte) END_MESSAGE_MAP() @@ -295,6 +300,7 @@ void CBasicPage::updateCmbDuplex(BOOL insert) m_cmBoxDuplex->InsertString(4, TEXT("对折")); } } +#ifdef G200 if (m_Slider_Dpi.m_iPosition > 300 && m_cmBoxSS->GetCount() > 20) { if (m_cmBoxSS->GetCurSel() >= 20) @@ -309,6 +315,7 @@ void CBasicPage::updateCmbDuplex(BOOL insert) m_cmBoxSS->InsertString(21, _T("最大扫描尺寸")); m_cmBoxSS->InsertString(22, _T("三联试卷")); } +#endif // G200 #ifndef G300 if (tmp_paperindex == 19 || tmp_paperindex == 20 || tmp_paperindex == 21 || tmp_paperindex == 22 || tmp_paperindex == 1|| tmp_paperindex == 4|| tmp_paperindex == 5){ (((CButton*)GetDlgItem(IDC_CKBSIZEDETECT)))->SetCheck(false); @@ -330,10 +337,6 @@ void CBasicPage::updateCmbDuplex(BOOL insert) } - - - - void CBasicPage::OnNMReleasedcaptureSliderdpi(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 @@ -368,3 +371,11 @@ void CBasicPage::OnNMReleasedcaptureSliderdpi(NMHDR* pNMHDR, LRESULT* pResult) #endif // G200 } + + +void CBasicPage::OnBnClickedBtnAttribyte() +{ + // TODO: 在此添加控件通知处理程序代码 + CAttributeDlg attributedlg(this); + attributedlg.DoModal(); +} diff --git a/huagao/CBasicPage.h b/huagao/CBasicPage.h index cd62f446..d599f177 100644 --- a/huagao/CBasicPage.h +++ b/huagao/CBasicPage.h @@ -55,4 +55,5 @@ private: public: afx_msg void OnCbnSelchangeCblowpowermode(); afx_msg void OnNMReleasedcaptureSliderdpi(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnBnClickedBtnAttribyte(); }; diff --git a/huagao/CFeedPaperPage.cpp b/huagao/CFeedPaperPage.cpp index d3c3e2ca..a5044608 100644 --- a/huagao/CFeedPaperPage.cpp +++ b/huagao/CFeedPaperPage.cpp @@ -61,6 +61,7 @@ void CFeedPaperPage::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_SLDDETECTLEVEL, m_sldSkrewDetecttion); DDX_Control(pDX, IDC_EDSCANNUM, m_editNum); DDX_Control(pDX, IDC_DogEarDetection, dogear); + DDX_Control(pDX, IDC_SLIDER_DOGEAR, m_slider_dogear); } BOOL CFeedPaperPage::OnInitDialog() @@ -72,6 +73,11 @@ BOOL CFeedPaperPage::OnInitDialog() OnInitcmBoxOrentation(0); m_sldSkrewDetecttion.SetSlideRange(1, 5); m_sldSkrewDetecttion.SetSlidePos(3); + + m_slider_dogear.SetSlideRange(10, 300); + m_slider_dogear.SetSlidePos(50); + m_slider_dogear.SetTicFreq(50); + #ifndef G200 for (size_t i = 0; i < g400hiden.size(); i++) { @@ -93,6 +99,7 @@ BEGIN_MESSAGE_MAP(CFeedPaperPage, CTabPageSSL) ON_BN_CLICKED(IDC_RDSPECIFYSCANNUM, &CFeedPaperPage::OnBnClickedScanMode) ON_BN_CLICKED(IDC_CKSKEWDETECT, &CFeedPaperPage::OnBnClickedCkskewdetect) ON_CBN_SELCHANGE(IDC_CMBORENTATION, &CFeedPaperPage::OnCbnSelchangeCmborentation) + ON_BN_CLICKED(IDC_DogEarDetection, &CFeedPaperPage::OnBnClickedDogeardetection) END_MESSAGE_MAP() BOOL CFeedPaperPage::PreTranslateMessage(MSG* pMsg) @@ -178,3 +185,15 @@ void CFeedPaperPage::OnCbnSelchangeCmborentation() // TODO: 在此添加控件通知处理程序代码 FeedPaperPageUpdate(comboxduplux); } + + +void CFeedPaperPage::OnBnClickedDogeardetection() +{ + // TODO: 在此添加控件通知处理程序代码 + UpdateData(TRUE); + if (((CButton*)GetDlgItem(IDC_DogEarDetection))->GetCheck() != 1) + m_slider_dogear.EnableWindow(FALSE); + else + m_slider_dogear.EnableWindow(TRUE); + +} diff --git a/huagao/CFeedPaperPage.h b/huagao/CFeedPaperPage.h index 53241242..b567014e 100644 --- a/huagao/CFeedPaperPage.h +++ b/huagao/CFeedPaperPage.h @@ -23,6 +23,7 @@ public: BOOL m_cbSkew; CComboBox m_cmBoxOrentation; CLinkSlider m_sldSkrewDetecttion; + CLinkSlider m_slider_dogear; int m_radioGroupScanMode; CSmartEdit m_editNum; @@ -47,4 +48,6 @@ private: public: afx_msg void OnCbnSelchangeCmborentation(); + + afx_msg void OnBnClickedDogeardetection(); }; diff --git a/huagao/CTwainUI.cpp b/huagao/CTwainUI.cpp index 65d6d559..2c777b3e 100644 --- a/huagao/CTwainUI.cpp +++ b/huagao/CTwainUI.cpp @@ -86,9 +86,14 @@ BOOL CTwainUI::OnInitDialog() UpdateUI(); UpdateListConfig(); dataChangeFunction(); - //setvisable_size(false); -#ifdef G200 +#ifdef ANDROIDSERIAL + setvisable_size(false); +#endif // ANDROIDSERIAL setvisable_sleepmode(false); +#ifdef G200 + setvisable_dogear(true); +#else + setvisable_dogear(false); #endif // G200 return true; } @@ -234,6 +239,8 @@ void CTwainUI::UpdateUI() m_pageFeedPaper->m_cmBoxOrentation.SetCurSel(settings->is_autotext?4:getRotateCmbIndex(settings->imageRotateDegree));//旋转方向; m_pageFeedPaper->m_sldSkrewDetecttion.SetPos(m_pageFeedPaper->m_cbSkew?settings->hardwarecaps.skrewdetectlevel:3);//歪斜检测等级 m_pageFeedPaper->m_sldSkrewDetecttion.EnableWindow(m_pageFeedPaper->m_cbSkew); + m_pageFeedPaper->m_slider_dogear.SetPos(settings->dogeardistance); + m_pageFeedPaper->m_slider_dogear.EnableWindow(((CButton*)m_pageFeedPaper->GetDlgItem(IDC_DogEarDetection))->GetCheck()); ((CComboBox*)m_pageFeedPaper->GetDlgItem(IDC_CBLOWPOWERMODE))->SetCurSel(settings->hardwarecaps.lowpowermode); if (settings->scannum == 65535)//连续扫描 { @@ -515,6 +522,7 @@ void CTwainUI::UpDateScanParam(PCONFIGPARAMS configItem, bool updateDs) settings->hardwarecaps.skrewdetectlevel = (int)configItem->ScrewDetectLevel; settings->hardwarecaps.en_stapledetect = configItem->EnBindingDetect; settings->hardwarecaps.en_doublefeed = configItem->EnUltrasonicDetect; + settings->dogeardistance = m_pageFeedPaper->m_slider_dogear.GetPos(); settings->en_fold = configItem->EnFlod ? 1 : 0; if (configItem->ScanCount == -1) settings->scannum = configItem->ScanCount; @@ -638,6 +646,16 @@ void CTwainUI::setvisable_sleepmode(bool flag) ((CComboBox*)m_pageFeedPaper->GetDlgItem(IDC_CBLOWPOWERMODE))->SetCurSel(0); } +void CTwainUI::setvisable_dogear(bool flag) +{ + m_pageFeedPaper->GetDlgItem(IDC_DogEarDetection)->ShowWindow(flag ? SW_SHOW : SW_HIDE); + m_pageFeedPaper->GetDlgItem(IDC_SLIDER_DOGEAR)->ShowWindow(flag ? SW_SHOW : SW_HIDE); + m_pageFeedPaper->GetDlgItem(IDC_LBSDL2)->ShowWindow(flag ? SW_SHOW : SW_HIDE); + m_pageFeedPaper->GetDlgItem(IDC_LBSDR2)->ShowWindow(flag ? SW_SHOW : SW_HIDE); + if (!flag) + ((CButton*)m_pageFeedPaper->GetDlgItem(IDC_DogEarDetection))->SetCheck(false); +} + void CTwainUI::EnableID_OKorID_Cancel(bool enable) { GetDlgItem(IDC_CONFIRM)->EnableWindow(enable); diff --git a/huagao/CTwainUI.h b/huagao/CTwainUI.h index feb1e336..ecec415e 100644 --- a/huagao/CTwainUI.h +++ b/huagao/CTwainUI.h @@ -175,6 +175,7 @@ public: void UpdateUi(); void setvisable_size(bool flag); void setvisable_sleepmode(bool flag); + void setvisable_dogear(bool flag); void EnableID_OKorID_Cancel(bool enable); // 对话框数据 #ifdef AFX_DESIGN_TIME diff --git a/huagao/Device/G400ScanConfig.cpp b/huagao/Device/G400ScanConfig.cpp index 511f6833..2a16e9e5 100644 --- a/huagao/Device/G400ScanConfig.cpp +++ b/huagao/Device/G400ScanConfig.cpp @@ -38,3 +38,37 @@ unsigned int G400ScanConfig::GetData() { return cfg.value; } + + +G400AndroidScanConfig::G400AndroidScanConfig(GScanCap& gcap) +{ + cfg = { 0 }; + 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) + cfg.params.isColor = 1; + else + cfg.params.isColor = SupPixelTypes[gcap.pixtype]; + //cfg.params.isColor = 1; + cfg.params.isCorrect = 1;//1 У + PaperStatus ps = { gcap.papertype,gcap.paperAlign }; + cfg.params.pageSize = SupPaperTyps[ps]; + CSize size; +#ifdef G300 + size = PaperSize.GetPaperSize(TwSS::A4, 200.0f, gcap.paperAlign);//G300 ֧A4 +#else + size = PaperSize.GetPaperSize(gcap.papertype, 200.0f, gcap.paperAlign); +#endif// G300 + cfg.params.dstHeight = (int)((size.cy + 200) / 100); + cfg.params.reversed1 = cfg.params.reversed2 = cfg.params.reversed3 = 0; +} + +G400AndroidScanConfig::~G400AndroidScanConfig() +{ +} + +unsigned int G400AndroidScanConfig::GetData() +{ + return cfg.value; +} diff --git a/huagao/Device/G400ScanConfig.h b/huagao/Device/G400ScanConfig.h index 0002bee9..429a86d7 100644 --- a/huagao/Device/G400ScanConfig.h +++ b/huagao/Device/G400ScanConfig.h @@ -33,3 +33,32 @@ private: Device::PaperSize PaperSize; }; + +class G400AndroidScanConfig : + public IConfig +{ +public: + union Configuration + { + struct + { + unsigned int pageSize : 5; + unsigned int isColor : 1; + unsigned int dpi : 2; + unsigned int doubleFeeded : 1; + unsigned int reversed3 : 1; + unsigned int enableLed : 1; + unsigned int reversed1 : 6; + unsigned int isCorrect : 1; + unsigned int dstHeight : 8; + unsigned int reversed2 : 6; + }params; + unsigned int value; + }; + G400AndroidScanConfig(GScanCap& gcap); + virtual ~G400AndroidScanConfig(); + virtual unsigned int GetData() override; +private: + Configuration cfg; + Device::PaperSize PaperSize; +}; diff --git a/huagao/Device/GScan.h b/huagao/Device/GScan.h index ef9bba92..5567b77b 100644 --- a/huagao/Device/GScan.h +++ b/huagao/Device/GScan.h @@ -140,7 +140,6 @@ class IScanner public: IScanner() { imgreadednum = imgtransfered = roller_num = lose_image_num = 0; - is_Android = false; } virtual ~IScanner() { @@ -149,32 +148,44 @@ public: /// ñɨ /// /// - void set_scannum(int val) { scannum = val; }; + void set_scannum(int val) { + scannum = val; + }; /// /// ȡɨ /// /// - int get_scannum() { return scannum; }; + int get_scannum() { + return scannum; + }; /// /// ȡPCȡͼҳ /// /// - int get_imgnReaded() { return imgreadednum; }; + int get_imgnReaded() { + return imgreadednum; + }; /// /// ȡͼ /// /// - int get_imgTransfered() { return imgtransfered; }; + int get_imgTransfered() { + return imgtransfered; + }; /// /// ȡʧͼ /// /// - int get_lose_image_num() { return lose_image_num; }; + int get_lose_image_num() { + return lose_image_num; + }; /// /// öʧͼ /// /// - void set_lose_image_num(int value) { lose_image_num = value; }; + void set_lose_image_num(int value) { + lose_image_num = value; + }; /// /// ȡԭʼͼԼһ /// @@ -263,7 +274,6 @@ protected: int roller_num; int scannum; int lose_image_num; - bool is_Android; int error_index; }; \ No newline at end of file diff --git a/huagao/Device/GScanO1003399.cpp b/huagao/Device/GScanO1003399.cpp index d2a81a6a..56496f29 100644 --- a/huagao/Device/GScanO1003399.cpp +++ b/huagao/Device/GScanO1003399.cpp @@ -246,6 +246,7 @@ void GScanO1003399::config_params(GScanCap& param) } cfg.g200params.dpi = SupResolutions.count(param.resolution_native)>0 ? SupResolutions[param.resolution_native] : 1; cfg.g200params.double_feed_enbale = (unsigned int)param.hardwarecaps.en_doublefeed; + //cfg.g200params.stable_enbale = 0; cfg.g200params.stable_enbale = (unsigned int)param.hardwarecaps.en_stapledetect; cfg.g200params.screw_detect_enable = (unsigned int)param.hardwarecaps.en_skrewdetect; cfg.g200params.screw_detect_level = (unsigned int)cfg.g200params.screw_detect_enable ? secrewMaps[param.hardwarecaps.skrewdetectlevel] : 0; @@ -313,6 +314,7 @@ void GScanO1003399::config_params(GScanCap& param) param39.papertype = param.papertype; param39.pixtype = param.pixtype; param39.resolution_dst = param.resolution_dst; + //param39.resolution_dst = param.resolution_dst > 300 ? 300 : param.resolution_dst; param39.resolution_native = param.resolution_native; param39.scannum = param.scannum; param39.sharpen = param.sharpen; @@ -320,7 +322,25 @@ void GScanO1003399::config_params(GScanCap& param) param39.multiOutput = MultiOutput::Unused; param39.normalCrop = param.normalCrop; m_usb->write_bulk(¶m39, sizeof(param39)); - + if (param.is_autotext) + { + TCHAR szIniFile[MAX_PATH] = { 0 }; + SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE); +#ifdef LANXUM + _tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata")); +#elif defined AUGE + _tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\tessdata")); +#elif defined HANVON + _tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\tessdata")); +#else + _tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata")); +#endif // + int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL); + char* chRtn = new char[iLen * sizeof(char)]; + WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL); + m_autotext.reset(new CImageApplyRotation(CImageApplyRotation::RotationType::AutoTextOrientation, false, param.resolution_dst, chRtn)); + delete[] chRtn; + } } void GScanO1003399::Scanner_StartScan(UINT16 count) @@ -427,7 +447,7 @@ void GScanO1003399::Stop_scan() int GScanO1003399::notifyscan() { - return 0; + return 1; } void GScanO1003399::ResetScanner() @@ -693,7 +713,6 @@ int GScanO1003399::read_data(void* data, int length, int timeout) int reading = 0; const int buffer_size = 512 * 1024; StopWatch sw; - FileTools::writelog(log_INFO, "read_data timeout =" + to_string(timeout)); while (readed < length) { if (sw.elapsed_ms() < timeout &&m_usb.get()) { @@ -762,32 +781,7 @@ void GScanO1003399::imgproce(std::shared_ptr>& buff) buffs.clear(); if (m_param.is_autotext) { - CImageApplyRotation::RotationType type; - /*if (m_param.imageRotateDegree > 89.0f && m_param.imageRotateDegree < 91.0f) - type = CImageApplyRotation::RotationType::Rotate_90_clockwise; - else if (m_param.imageRotateDegree > 269.0f && m_param.imageRotateDegree < 271.0f) - type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise; - else if (m_param.imageRotateDegree > 179.0f && m_param.imageRotateDegree < 181.0f) - type = CImageApplyRotation::RotationType::Rotate_180; - else*/ - - if (m_param.is_autotext) - type = CImageApplyRotation::RotationType::AutoTextOrientation; - else - type = CImageApplyRotation::RotationType::Invalid;//ֻԶıʶ IJ - - TCHAR szIniFile[MAX_PATH] = { 0 }; - SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE); -#ifdef LANXUM - _tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata")); -#else - _tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata")); -#endif // - int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL); - char* chRtn = new char[iLen * sizeof(char)]; - WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL); - CImageApplyRotation(type, m_param.is_backrotate180, m_param.resolution_dst, chRtn).apply(mats,m_param.is_duplex); - delete[] chRtn; + m_autotext->apply(mats, m_param.is_duplex); } if (m_param.automaticcolor) { diff --git a/huagao/Device/GScanO1003399.h b/huagao/Device/GScanO1003399.h index 62ef67c4..660181e6 100644 --- a/huagao/Device/GScanO1003399.h +++ b/huagao/Device/GScanO1003399.h @@ -83,6 +83,7 @@ private: BlockingQueue m_paths; //std::queue> fu_imgpro; + std::shared_ptr m_autotext; std::shared_ptr m_imgprocthread; std::shared_ptr m_usbthread; std::shared_ptr> im_data; diff --git a/huagao/Device/GScanO200.cpp b/huagao/Device/GScanO200.cpp index 893d83fd..3099d886 100644 --- a/huagao/Device/GScanO200.cpp +++ b/huagao/Device/GScanO200.cpp @@ -446,7 +446,7 @@ void GScanO200::Scanner_StartScan(UINT16 count) int GScanO200::notifyscan() { - return -1; + return 1; } void GScanO200::Stop_scan() diff --git a/huagao/Device/GScanO400.cpp b/huagao/Device/GScanO400.cpp index 461592bb..eaa0bcbf 100644 --- a/huagao/Device/GScanO400.cpp +++ b/huagao/Device/GScanO400.cpp @@ -187,10 +187,6 @@ void GScanO400::open(int vid, int pid) USBCB status = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) { - //m_usb->write_bulk(&status, sizeof(status)); - //m_usb->read_bulk(&status, sizeof(status)); - //std::this_thread::sleep_for(std::chrono::milliseconds(20)); - //notifyscan(); GetFWVersion(); } } @@ -264,10 +260,6 @@ std::string GScanO400::GetFWVersion() m_usb->read_bulk(&fwVersion[0], fwVersion.size()); std::this_thread::sleep_for(chrono::milliseconds(10)); } - if (fwVersion.substr(0, 2) == "G3" || fwVersion.substr(0, 2) == "G4" ||fwVersion.substr(0,2)== "GU") - is_Android = false; - else - is_Android = true; return fwVersion; } return ""; @@ -431,7 +423,6 @@ void GScanO400::Scanner_StartScan(UINT16 count) devState = DEV_WRONG; int errorcode = 0; readlenght == 0 ? errorcode = USB_DISCONNECTED : errorcode = NO_FEED; - Set_ErrorCode(errorcode); if (huagods) dev_callback(errorcode, huagods); @@ -617,8 +608,6 @@ void GScanO400::usbmain() this_thread::sleep_for(chrono::milliseconds(200)); break; } - - if (sw.elapsed_ms() > 30000) { m_pImages->setscanflags(false); @@ -667,9 +656,7 @@ void GScanO400::usbmain() #else UpdateScanInfo(countNReaded(), get_imgTransfered()); #endif - - if (!is_Android) - Pop_Image(); + Pop_Image(); FileTools::writelog(log_INFO, "ɨǽ" + to_string(get_imgnReaded()) + "ļʱ " + to_string(sw.elapsed_ms())); sw.reset(); break; @@ -677,7 +664,7 @@ void GScanO400::usbmain() case STOP_SCAN: { m_pImages->setscanflags(false); - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; break; } @@ -695,25 +682,11 @@ void GScanO400::usbmain() case USB_BULK_ERROR: if (!haveError) { - //if (is_Android) - //{ haveError = true; Set_ErrorCode(usbcb.u32_Data); - //} - //else - //{ - // haveError = true; - // devState = DEV_WRONG; - // m_pImages->setscanflags(false); - // Set_ErrorCode(usbcb.u32_Data); - // std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - // auto rollernew = Get_Roller_num(); - // if (get_aquire_image_count() != (rollernew - roller_num)) - // set_lose_image_num(std::abs((rollernew - roller_num) - get_aquire_image_count())); - //} + if (huagods) dev_callback(usbcb.u32_Data, huagods); - } break; case NORMAL: @@ -726,12 +699,8 @@ void GScanO400::usbmain() } catch (const std::exception& e) { - //writelog(e.what()); FileTools::writelog(log_ERROR, e.what()); } - - ////FileTools::write_log("D:\\1.txt", "thread usb exit"); - } /////////////////////////////////////////////////////////////////////////// @@ -745,18 +714,6 @@ USBCB GScanO400::Get_Scanner_Status() m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&usbcb, sizeof(usbcb)); - if (usbcb.u32_CMD != GET_DSP_STATUS) - { - std::this_thread::sleep_for(std::chrono::microseconds(50)); - if (m_usb.get() && m_usb->is_connected()) - m_usb->read_bulk(&usbcb, 512); - if (m_usb.get() && m_usb->is_connected()) - m_usb->write_bulk(&usbcb, sizeof(usbcb)); - if (m_usb.get() && m_usb->is_connected()) - m_usb->read_bulk(&usbcb, 512); - FileTools::writelog(log_ERROR, "get dsp status error"); - return { NO_COMMAND,USB_BULK_ERROR,0 }; - } return usbcb; } @@ -768,26 +725,6 @@ std::shared_ptr> GScanO400::Get_Img_Data(int bufferSize) return std::shared_ptr>(new std::vector()); std::shared_ptr> imData(new std::vector(bufferSize)); - /*StopWatch sw; - int readed = 0; - USBCB usbcb = { GET_IMAGE,0,bufferSize }; - m_usb->write_bulk(&usbcb, sizeof(usbcb)); - int totalength = bufferSize; - int startindex = 0; - while (totalength > 0) - { - int dstlength = 1024 * 1024; - if (totalength <= dstlength) - { - dstlength = totalength; - totalength = 0; - } - else - totalength -= dstlength; - - int tt = m_usb->read_bulk(imData->data() + startindex, dstlength); - startindex += dstlength; - }*/ StopWatch sw; int readed = 0; USBCB usbcb = { GET_IMAGE,0,bufferSize }; diff --git a/huagao/Device/GScanO400.h b/huagao/Device/GScanO400.h index 86a66138..a45d3f34 100644 --- a/huagao/Device/GScanO400.h +++ b/huagao/Device/GScanO400.h @@ -1,7 +1,7 @@ #pragma once #include "GScan.h" #include - +#include "StopWatch.h" class GScanO400 : public IScanner { diff --git a/huagao/Device/GScanO400Android.cpp b/huagao/Device/GScanO400Android.cpp new file mode 100644 index 00000000..72baa2cb --- /dev/null +++ b/huagao/Device/GScanO400Android.cpp @@ -0,0 +1,810 @@ +#include "stdafx.h" +#include "GScanO400Android.h" +#include "UsbScanEx.h" +#include "StopWatch.h" +#include "scn_config.h" +#include "ImageMatQueue.h" +#include "ImageProcess/ImageApplyDogEarDetection.h" +#include "filetools.h" +#include "GetMemoryUsage.h" +#include "G400ScanConfig.h" + +//u32_CMD +typedef enum tagUsbKeyWords : UINT32 +{ + // + NO_COMMAND = 0, + //ȡdsp ״̬ + GET_DSP_STATUS = 1, + //ȡͼ + GET_IMAGE = 2, + //DSPפͼ + POP_IMAGE = 3, + //ʼɨ + START_COMMAND = 4, + //ֹͣɨ + STOP = 5, + //ȡɨɨģʽ + GET_SCAN_MODE = 6, + //ȡ̼汾 + GET_FW_VERSION = 7, + //PC˵״̬ + SEND_STATUS_PC = 8, + //·ɨò + CONFIGURED_DATA = 9, + //·̼Ϣ + SEND_FW = 10, + //ȡɨ + GET_CONFIG_DATA = 11, + //ȡɨ + GET_SCANN_NUM = 12, + //ȡֽ״̬ + GET_PAPERFEEDER_STATUS = 13, + //DSPʼ + INIT_HARDWARE_SYS = 14, + //ȡֽ״̬ + GET_PAPER_STATUS = 0x0d, + //·ԪòҶȣLED Rعʱ䣩 + SEND_COMPONENTS_GR = 15, + //·ԪòLED G/Bعʱ䣩 + SEND_COMPONENTS_GB = 16, + //·ɨģʽ + SEND_SCAN_MODE = 17, + //ʼƽ + START_FLAT = 18, + //ֹͣƽ + STOP_FLAT = 19, + //·200dpiɫƽ + SEND_200_COLOR_FLAT_DATA = 20, + //·300dpiɫƽ + SEND_300_COLOR_FLAT_DATA = 21, + //ȡ200dpiɫƽ + GET_200_COLOR_FLAT_DATA = 22, + //ȡ300dpiɫƽ + GET_300_COLOR_FLAT_DATA = 23, + //·200dpiҶƽУ + SEND_200_GRAY_FLAT_DATA = 24, + //·300dpiҶƽУ + SEND_300_GRAY_FLAT_DATA = 25, + //ȡ200DPIҶƽУ + GET_200_GRAY_FLAT_DATA = 26, + //ȡ300DPIҶƽУ + GET_300_GRAY_FLAT_DATA = 27, + //·к + SEND_SERIAL = 28, + //ȡк + GET_SERIAL = 29, + //ȡ + GET_ROLLER_NUM = 0x1e, + // + CLR_ROLLER_NUM = 0x1f, + //ɨ + CLR_SCAN_NUM = 0x20, + //׼¹̼ + PRE_UPGRADE = 0X21, + //ʼ¹̼ + START_UPGRADE = 0x22, + //ɫAD + RGB_ADI_PARA = 0x23, + //ҶȵAD + ADI_PARA = 0x24, + //ȡCISعʱ䣬ad) + GET_CIS_PARA = 0x25, + //ɨ + START_COMMAND_COUNT = 0x26, + //·ʱ + SET_SLEEP_TIME = 0x27, + //ȡʱ + GET_SLEEP_TIME = 0x28, + // + CLR_CACHE = 0x29, + //·ٶģʽ + SET_SPEED_MODE = 0x2a, + //ȡɨٶģʽ + GET_SPEED_MODE = 0X2b, + //ù̼汾һ8ֽ + SET_FW_VERSION = 0X2c, + //ȡDSP汾 + GET_DSP_VERSION = 0X2d, + //ɼFPGA̼汾 + GET_SCANFPGA_VERSION = 0x2e, + //FPGA̼汾 + GET_MOTORFPGA_VERSION = 0X2f, + //Ϣ + SET_USB_INFOR_MANUFACTURE = 0X30, + //ȡϢ + GET_USB_INFOR_MANUFACTURE = 0X31, + //òƷͺϢ + SET_USB_INFOR_MODEL_NAME = 0X32, + //ȡƷͺϢ + GET_USB_INFOR_MODEL_NAME = 0X33, + //USB PID / VIDϢ + SET_USB_INFOR_VIDPID = 0X34, + GET_USB_INFOR_VIDPID = 0X35, + //ÿֽͣ + SET_JAM_DETECT_SENSITIVE = 0X36, + //ȡֽͣ + GET_JAM_DETECT_SENSITIVE = 0X37, + //úϵ + SET_JUST_COF_H = 0x38, + //ȡϵ + GET_JUST_COF_H = 0x39, + CLEAR_HWERROR = 0x40,//G400 Ӳ쳣 + //ϵ + SET_JUST_COF_V = 0x41, + //ȡϵ + GET_JUST_COF_V = 0x42, + //ɨDZ + GET_CODE_G400 = 0x59, + //ȡɨDZ + SET_CODE_G400 = 0x60, + //ɨDZ + SET_CODE_G200 = 0x63, + //ȡɨDZ + GET_CODE_G200 = 0x64, + +} UsbKeyWords, * PUsbKeyWords; + +GScanO400Android::GScanO400Android() : + huagods(NULL), + image_num(0), + m_bread_fixed_ratio_fromDSP(false) +{ + m_pImages.reset(new ImageMatQueue()); + auto getimgnum = [&](bool isadd, int num) + { + isadd ? image_num += num : image_num -= num; + }; + m_pImages->SetGetimgnumcall(getimgnum); +} + +GScanO400Android::~GScanO400Android() +{ + if (m_threadUsb && m_threadUsb->joinable()) { + devState = DEV_STOP; + m_threadUsb->join(); + m_threadUsb.reset(); + } + if (m_usb.get()) + m_usb.reset(); + +} + +void GScanO400Android::DogEar_callback(std::function fun) +{ + m_pImages->SetDogEarCallback(fun); +} + +void GScanO400Android::open(int vid, int pid) +{ + auto usbs = UsbScan_List::find_vid_pid(vid, pid); + + if (!usbs.empty()) + { + m_usb = *usbs.begin(); + m_usb->set_usbhotplug_callback(usbhotplug_callback, this); + bool ret = m_usb->open(); + USBCB status = { GET_DSP_STATUS ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + { + //m_usb->write_bulk(&status, sizeof(status)); + //m_usb->read_bulk(&status, sizeof(status)); + //std::this_thread::sleep_for(std::chrono::milliseconds(20)); + //notifyscan(); + GetFWVersion(); + } + } +} + +void GScanO400Android::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata) +{ + huagods = usrdata; + dev_callback = callback; +} + +int GScanO400Android::aquire_bmpdata(std::vector& bmpdata) +{ + StopWatch sw; + while (true) + { + if (m_pImages->empty()) { + DoEvents(); + this_thread::sleep_for(chrono::milliseconds(1)); + if (sw.elapsed_s() > 30.00) + { + int roller_num_new = Get_Roller_num(); + if (m_threadUsb && m_threadUsb->joinable()) { + devState = DEV_STOP; + m_threadUsb->join(); + m_threadUsb.reset(); + FileTools::writelog(log_ERROR, "aquire_bmpdata m_threadUsb.reset()"); + } + Stop_scan();//ֹͣɨ + ResetScanner(); + set_scannum(abs(roller_num_new - roller_num)); + return HARDWARE_ERROR; + } + + if (!is_scan()) { + int roller_num_new = Get_Roller_num(); + set_scannum(abs(roller_num_new - roller_num)); + if (devState == DEV_WRONG) { + return get_ErrorCode(); + } + return -1; + } + } + else { + if (m_pImages->valid()) { + bmpdata = *(m_pImages->popBmpdata()); + UpdateScanInfo(get_imgnReaded(), countNTransfered()); + return 0; + } + DoEvents(); + this_thread::sleep_for(chrono::milliseconds(2)); + } + } +} + +BOOL GScanO400Android::IsConnected() +{ + return m_usb.get() && m_usb->is_connected(); +} + +std::string GScanO400Android::GetFWVersion() +{ + if (m_usb.get() && m_usb->is_connected()) { + //lock_guard< mutex> lock(m_imgLocker); + if (fwVersion.empty()) { + fwVersion.resize(10); + USBCB cmd = { GET_FW_VERSION,fwVersion.size(),0, }; + m_usb->write_bulk(&cmd, sizeof(cmd)); + std::this_thread::sleep_for(chrono::milliseconds(10)); + if (m_usb.get() && m_usb->is_connected()) + m_usb->read_bulk(&fwVersion[0], fwVersion.size()); + std::this_thread::sleep_for(chrono::milliseconds(10)); + } + //if (fwVersion.substr(0, 2) == "G3" || fwVersion.substr(0, 2) == "G4" ||fwVersion.substr(0,2)== "GU") + // is_Android = false; + //else + // is_Android = true; + return fwVersion; + } + return ""; +} + +std::string GScanO400Android::GetSerialNum() +{ + //return "G20018000298"; + if (m_usb.get() && m_usb->is_connected()) + { + std::lock_guard lck(m_imgLocker); + if (SerialNum.empty()) { + SerialNum.resize(14); + USBCB usbcb = { GET_SERIAL,SerialNum.size(),0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + if (m_usb.get() && m_usb->is_connected()) + m_usb->read_bulk(&SerialNum[0], SerialNum.size()); + } + return SerialNum; + } + return ""; +} + +std::uint32_t GScanO400Android::GetMotorFPGA() +{ + if (m_usb.get() && m_usb->is_connected()) + { + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { GET_MOTORFPGA_VERSION,0,sizeof(MotorFpga) }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + MotorFpga = usbcb.u32_Data; + return MotorFpga; + } + return 0; +} + +std::uint32_t GScanO400Android::GetScanFPGA() +{ + if (m_usb.get() && m_usb->is_connected()) + { + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { GET_SCANFPGA_VERSION,0,4 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + ScanFpga = usbcb.u32_Data; + return ScanFpga; + } + return 0; +} + + +bool GScanO400Android::is_scan() +{ + //std::lock_guard lck(m_imgLocker); + return devState == DEV_ISRUNNING; +} + +BOOL GScanO400Android::Get_Scanner_PaperOn() +{ + if (!(m_usb.get() && m_usb->is_open())) + { + Set_ErrorCode(USB_DISCONNECTED); + return true; + } + + USBCB usbcb = { GET_PAPER_STATUS ,2,0 }; + std::lock_guard lck(m_imgLocker); + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + if (m_usb.get() && m_usb->is_connected()) { + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + if (usbcb.u32_Data == 2) + { + Set_ErrorCode(USB_DISCONNECTED); + return true; + } + } + else { + Set_ErrorCode(USB_DISCONNECTED); + return true; + } + return usbcb.u32_Data != 0; +} + +int GScanO400Android::Get_Roller_num() +{ + if (!(m_usb.get() && m_usb->is_open())) + return false; + USBCB usbcb = { GET_ROLLER_NUM ,0,4 }; + std::lock_guard lck(m_imgLocker); + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + if (usbcb.u32_CMD != GET_ROLLER_NUM) + { + FileTools::writelog(log_ERROR, "get roller usb bulk error"); + } + FileTools::writelog(log_INFO, "get roller num " + to_string(usbcb.u32_Data)); + return usbcb.u32_Data; +} + +void GScanO400Android::config_params(GScanCap& params) +{ + + if (m_usb.get() && m_usb->is_connected()) { + G400AndroidScanConfig cfg = G400AndroidScanConfig(params); + gcap = params; + UINT32 cfgdata = cfg.GetData(); + USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; + FileTools::writelog(log_INFO, "config hardware param" + to_string(cfgdata)); + m_usb->write_bulk(&usbcb, sizeof(USBCB)); + this_thread::sleep_for(std::chrono::milliseconds(200)); + m_pImages->setparam(params); + } +} + +void GScanO400Android::Scanner_StartScan(UINT16 count) +{ + scanfalg = false; + Set_ErrorCode(0); + roller_num = Get_Roller_num(); + std::lock_guard lck(m_imgLocker); + if (m_threadUsb && m_threadUsb->joinable()) { + devState = DEV_STOP; + m_threadUsb->join(); + } + USBCB status = { GET_DSP_STATUS ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&status, sizeof(status)); + if (m_usb.get() && m_usb->is_connected()) + m_usb->read_bulk(&status, sizeof(status)); + switch (status.u32_Data) + { + case COUNT_MODE: + case NO_FEED: + case OPEN_COVER: + case FEED_IN_ERROR: + case PAPER_JAM: + case DETECT_DOUBLE_FEED: + case DETECT_STAPLE: + case PAPER_SKEW: + case HARDWARE_ERROR: + case PC_SCAN_BUSY_or_ERROR: + m_pImages->setscanflags(false); + devState = DEV_WRONG; + Set_ErrorCode(status.u32_Data); + if (huagods) + dev_callback(status.u32_Data, huagods); + return; + default: + break; + } + + int readlenght = 0; + USBCB paperstatus = { GET_PAPER_STATUS ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&paperstatus, sizeof(paperstatus)); + if (m_usb.get() && m_usb->is_connected()) + readlenght = m_usb->read_bulk(&paperstatus, sizeof(paperstatus)); + if (paperstatus.u32_Data == 0) { + m_pImages->setscanflags(false); + devState = DEV_WRONG; + int errorcode = 0; + readlenght == 0 ? errorcode = USB_DISCONNECTED : errorcode = NO_FEED; + + Set_ErrorCode(errorcode); + if (huagods) + dev_callback(errorcode, huagods); + return; + } + m_pImages->reset_DogEar(); + if (gcap.is_duplex) + count = count == 65535 ? 65535 : count / 2; + USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + this_thread::sleep_for(std::chrono::milliseconds(200)); + if (m_usb.get() && m_usb->is_connected()) + { + m_pImages->setscanflags(true); + m_threadUsb.reset(new std::thread(&GScanO400Android::usbmain, this)); + m_pImages->run(); + } +} + +int GScanO400Android::notifyscan() +{ + //if (!m_usb.get() && !m_usb->is_connected()) + // return -1; + //USBCB notify = { 0x100,0,0 }; + //m_usb->write_bulk(¬ify, sizeof(notify)); + //m_usb->read_bulk(¬ify, sizeof(notify)); + //if ((notify.u32_Data != 0x10 && GetFWVersion().length() < 10) || notify.u32_Data == 0x100) + //{ + // ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("ɨǴ״̬,밴Դѣ ʾ "), NULL, SW_HIDE); + // return -1; + //} + return 1; +} + + +void GScanO400Android::Stop_scan() +{ + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { STOP ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + { + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + scanfalg = true; + FileTools::writelog(log_INFO, "user stop scan"); + } +} + + +void GScanO400Android::ResetScanner() +{ + if (!(m_usb.get() && m_usb->is_connected())) + return; + + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&usbcb, sizeof(usbcb)); +} + +bool GScanO400Android::Get_IsImageQueueEmpty() +{ + return m_pImages->empty(); +} + +void GScanO400Android::reset() +{ + while (!m_pImages->empty()) + m_pImages->clear(); +} + + +UINT32 GScanO400Android::get_ErrorCode() +{ + return Error_Code; +} + +void GScanO400Android::Set_ErrorCode(UINT32 value) +{ + Error_Code = value; +} + +int GScanO400Android::get_scanned_num() +{ + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { GET_SCANN_NUM ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + + return usbcb.u32_Count; +} + +void GScanO400Android::clear_hwerror() +{ + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { CLEAR_HWERROR ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&usbcb, sizeof(usbcb)); +} + +void GScanO400Android::set_sleep_time(int mode) +{ + return; +} + +bool GScanO400Android::set_scannercode(std::string str) +{ + if (str.size() != 32) + return false; + if (!(m_usb.get() && m_usb->is_connected())) + return false; + for (int i = 0; i < str.size(); i += 4) + { + USBCB usbcb = { SET_CODE_G400,UINT32(str[i]) + ((UINT32(str[i + 1])) << 8) + (((UINT32)str[i + 2]) << 16) + (((UINT32)str[i + 3]) << 24),i }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + } + return true; +} + +std::string GScanO400Android::get_scannercode() +{ + if (!(m_usb.get() && m_usb->is_connected())) + return NULL; + USBCB usb{ GET_CODE_G400,0,32 }; + m_usb->write_bulk(&usb, sizeof(USBCB)); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + scannercode.resize(32); + m_usb->read_bulk(&scannercode[0], 32); + return scannercode.c_str(); +} + +void GScanO400Android::usbhotplug_callback(bool isconnect, void* userdata) +{ + GScanO400Android* This = (GScanO400Android*)userdata; + This->usbhotplug(isconnect); +} + +void GScanO400Android::usbhotplug(bool isleft) +{ + FileTools::writelog(log_ERROR, "enable usb callback "); + if (isleft) { + devState = DEV_WRONG; + Error_Code = USB_DISCONNECTED; + m_pImages->setscanflags(false); + if (m_usb.get()) + m_usb.reset(); + if (huagods) + dev_callback(USB_DISCONNECTED, huagods); + } +} + +void GScanO400Android::updateHVRatio() +{ + if (!(m_usb.get() && m_usb->is_connected())) + return; + if (m_bread_fixed_ratio_fromDSP) { + USBCB usbcb = { GET_JUST_COF_H ,0,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + float hratio = *((float*)(&usbcb.u32_Data)); + usbcb = { GET_JUST_COF_V ,0,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + float vratio = *((float*)(&usbcb.u32_Data)); + m_pImages->updatefixratio(hratio, vratio); + } +} + +void GScanO400Android::usbmain() +{ + std::shared_ptr> imgData; + devState = DEV_ISRUNNING; + image_last = true; + bool haveError = false; + try + { + StopWatch sw; + while (devState == DEV_ISRUNNING) { + if (!(m_usb.get() && m_usb->is_connected())) { + this_thread::sleep_for(chrono::milliseconds(200)); + break; + } + if (sw.elapsed_ms() > 30000) + { + m_pImages->setscanflags(false); + Set_ErrorCode(AQUIRE_IMAGE_TIMEOUT); + devState = DevState::DEV_WRONG; + //devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; + FileTools::writelog(log_ERROR, "USBmain aquire image timeout"); + return; + } + + USBCB usbcb = Get_Scanner_Status(); + switch (usbcb.u32_Data) { + case HAVE_IMAGE: + { + int totalNum = usbcb.u32_Count&0x3fffffff; + if (totalNum < 1) + { + image_last = false; + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + m_usb->set_timeout(2000); + imgData = Get_Img_Data(totalNum); + m_usb->set_timeout(200); + if (!imgData->size()) { + Stop_scan(); + FileTools::writelog(log_ERROR, "imgData->size() error"); + break; + } + FileTools::writelog(log_INFO, " get image data size " + to_string(totalNum)); + if (imgData->size() != totalNum) + { + FileTools::writelog(log_ERROR, " get image data size error totalnum " + to_string(totalNum) + " imgdata size " + to_string(imgData->size())); + } + if (!m_pImages->get_isDogEar()) + m_pImages->pushMat(std::shared_ptr(new G400Decode(imgData))); + + UpdateScanInfo(countNReaded(), get_imgTransfered()); + FileTools::writelog(log_INFO, "ɨǽ" + to_string(get_imgnReaded()) + "ļʱ " + to_string(sw.elapsed_ms())); + sw.reset(); + break; + } + case STOP_SCAN: + { + //m_pImages->setscanflags(false); + //std::this_thread::sleep_for(std::chrono::milliseconds(500)); + devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; + break; + } + case COUNT_MODE: + case NO_FEED: + case OPEN_COVER: + case FEED_IN_ERROR: + case PAPER_JAM: + case DETECT_DOUBLE_FEED: + case DETECT_STAPLE: + case PAPER_SKEW: + case HARDWARE_ERROR: + case PC_SCAN_BUSY_or_ERROR: + case SIZE_ERROR: + case USB_BULK_ERROR: + if (!haveError) + { + haveError = true; + Set_ErrorCode(usbcb.u32_Data); + if (huagods) + dev_callback(usbcb.u32_Data, huagods); + } + break; + case NORMAL: + break; + default: + break; + } + this_thread::sleep_for(chrono::milliseconds(10)); + } + + while (image_last) + { + auto usbcb = Get_Scanner_Status(); + if (usbcb.u32_Data != 0x47) + { + this_thread::sleep_for(chrono::milliseconds(10)); + continue; + } + int totalNum = usbcb.u32_Count & 0x3fffffff; + if (totalNum < 1) + { + image_last = false; + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + m_usb->set_timeout(2000); + imgData = Get_Img_Data(totalNum); + m_usb->set_timeout(200); + if (!imgData->size()) { + Stop_scan(); + FileTools::writelog(log_ERROR, "imgData->size() error"); + break; + } + FileTools::writelog(log_INFO, " get image data size " + to_string(totalNum)); + if (imgData->size() != totalNum) + { + FileTools::writelog(log_ERROR, " get image data size error totalnum " + to_string(totalNum) + " imgdata size " + to_string(imgData->size())); + } + if (!m_pImages->get_isDogEar()) + m_pImages->pushMat(std::shared_ptr(new G400Decode(imgData))); + UpdateScanInfo(countNReaded(), get_imgTransfered()); + FileTools::writelog(log_INFO, "ɨǽ" + to_string(get_imgnReaded()) + "ļʱ " + to_string(sw.elapsed_ms())); + } + m_pImages->setscanflags(false); + + } + catch (const std::exception& e) + { + FileTools::writelog(log_ERROR, e.what()); + } +} + +/////////////////////////////////////////////////////////////////////////// +USBCB GScanO400Android::Get_Scanner_Status() +{ + if (!(m_usb.get() && m_usb->is_connected())) { + return { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 }; + } + USBCB usbcb = { GET_DSP_STATUS ,0,0 }; + if (m_usb.get() && m_usb->is_connected()) + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + if (m_usb.get() && m_usb->is_connected()) + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + //if (usbcb.u32_CMD != GET_DSP_STATUS) + //{ + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + // if (m_usb.get() && m_usb->is_connected()) + // m_usb->read_bulk(&usbcb, 512); + // FileTools::writelog(log_ERROR, "get dsp status error"); + // //return { NO_COMMAND,USB_BULK_ERROR,0 }; + //} + return usbcb; +} + +std::shared_ptr> GScanO400Android::Get_Img_Data(int bufferSize) +{ + try + { + bool ZLP = false; + if (!(m_usb.get() && m_usb->is_connected())) + return std::shared_ptr>(new std::vector()); + if ((bufferSize & 511) == 0) + { + bufferSize += 1; + ZLP = true; + } + std::shared_ptr> imData(new std::vector(bufferSize)); + StopWatch sw; + int readed = 0; + USBCB usbcb = { GET_IMAGE,0,bufferSize }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + this_thread::sleep_for(chrono::milliseconds(50)); + int totalength = 512 * 1024; + int startindex = 0; + std::this_thread::sleep_for(std::chrono::microseconds(20)); + while (startindex < bufferSize) + { + startindex += m_usb->read_bulk(imData->data() + startindex, (bufferSize - startindex) < totalength ? (bufferSize - startindex) : totalength); //ݽСڵڹܵʧ + std::this_thread::sleep_for(std::chrono::microseconds(10)); + if (ZLP &&(startindex == (bufferSize - 1))) + { + break; + } + } + if (sw.elapsed_ms() > 5000) + { + FileTools::writelog(log_ERROR, "Usb read data timeout\n"); + } + return imData; + } + catch (const std::exception& e) + { + FileTools::writelog(log_ERROR, e.what()); + } +} + +/////////////////////////////////////////////////////////////////////////// +void GScanO400Android::Pop_Image() +{ + if (!(m_usb.get() && m_usb->is_open())) + return; + + USBCB usbcb = { POP_IMAGE ,0,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); +} + diff --git a/huagao/Device/GScanO400Android.h b/huagao/Device/GScanO400Android.h new file mode 100644 index 00000000..c3972768 --- /dev/null +++ b/huagao/Device/GScanO400Android.h @@ -0,0 +1,59 @@ +#pragma once +#include "GScan.h" +#include +#include "StopWatch.h" + +class GScanO400Android : public IScanner +{ +public: + GScanO400Android(); + virtual ~GScanO400Android(); + // อจน IGScan ผฬณะ + virtual void open(int vid, int pid) override; + virtual void regist_deviceevent_callback(deviceevent_callback callback, void* usrdata = 0) override; + virtual int aquire_bmpdata(std::vector& bmpdata) override; + virtual BOOL IsConnected() override; + virtual std::string GetFWVersion() override; + virtual std::string GetSerialNum() override; + virtual std::uint32_t GetMotorFPGA() override; + virtual std::uint32_t GetScanFPGA() override; + virtual bool is_scan() override; + virtual BOOL Get_Scanner_PaperOn() override; + virtual int Get_Roller_num() override; + virtual void config_params(GScanCap& params) override; + virtual void Scanner_StartScan(UINT16 count) override; + virtual int notifyscan() override; + virtual void Stop_scan() override; + virtual void ResetScanner() override; + virtual bool Get_IsImageQueueEmpty() override; + virtual void reset() override; + virtual UINT32 get_ErrorCode() override; + virtual void Set_ErrorCode(UINT32 value) override; + virtual int get_scanned_num() override; + virtual void clear_hwerror() override; + virtual void set_sleep_time(int mode) override; + virtual bool set_scannercode(std::string str); + virtual std::string get_scannercode(); + virtual void DogEar_callback(std::function fun) override; + +private: + static void usbhotplug_callback(bool isleft, void* userdata); + void usbhotplug(bool isleft); + void updateHVRatio(); + void usbmain(); + USBCB Get_Scanner_Status(); + void Getimagenumber(bool isadd); + std::shared_ptr> Get_Img_Data(int buffersize); + void Pop_Image(); +private: + bool m_bread_fixed_ratio_fromDSP; + std::shared_ptr m_usb; + std::unique_ptr m_threadUsb; + GScanCap gcap; + volatile int image_num; + volatile bool scanfalg; + volatile bool image_last; + void* huagods; + deviceevent_callback dev_callback; +}; + diff --git a/huagao/Device/ImageMatQueue.cpp b/huagao/Device/ImageMatQueue.cpp index c4918e94..6b55413c 100644 --- a/huagao/Device/ImageMatQueue.cpp +++ b/huagao/Device/ImageMatQueue.cpp @@ -159,28 +159,13 @@ void ImageMatQueue::setparam(const GScanCap& param) //scanParam.imageRotateDegree = 90.0f; m_iaList.clear(); + if (scanParam.fillhole.is_fillhole) { float ratio = scanParam.fillhole.fillholeratio / 100.0; - m_iaList.push_back(shared_ptr(new CImageOutHole(200, ratio, 50))); + m_iaList.push_back(shared_ptr(new CImageApplyOutHole(200, ratio, 50))); } //ȷܹȡͼ - { - bool islongcustomcrop = param.papertype == TwSS::USStatement; - //bool isautocrop = param.papertype == TwSS::None; - CSize fixedSize; -#ifdef REAL300DPI - fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_dst > 240.0f ? 300.0f : 200.0f, param.paperAlign); -#else // REAL300DPI - fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign); -#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))); - /* 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)) - m_iaList.push_back(shared_ptr(new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(fixedSize.cx, fixedSize.cy), 1.0, 1.0)));*/ - } if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) { //m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank())); CImageApplyDiscardBlank* disBlank = new CImageApplyDiscardBlank(); @@ -228,6 +213,25 @@ void ImageMatQueue::setparam(const GScanCap& param) //m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(param.areanum,param.devnmax))); } + { + bool islongcustomcrop = param.papertype == TwSS::USStatement; + //bool isautocrop = param.papertype == TwSS::None; + CSize fixedSize; +#ifdef REAL300DPI + fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_dst > 240.0f ? 300.0f : 200.0f, param.paperAlign); +#else // REAL300DPI + fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign); +#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))); + + /* 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)) + m_iaList.push_back(shared_ptr(new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(fixedSize.cx, fixedSize.cy), 1.0, 1.0)));*/ + } + + //filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b if (param.filter != 3 || param.enhance_color) { int channel = 0; //filter none r g b enhance none r g b @@ -311,6 +315,8 @@ void ImageMatQueue::setparam(const GScanCap& param) SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE); #ifdef LANXUM _tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata")); +#elif defined AUGE + _tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\tessdata")); #elif defined HANVON _tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\tessdata")); #else @@ -322,6 +328,7 @@ void ImageMatQueue::setparam(const GScanCap& param) m_iaList.push_back(shared_ptr(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn))); delete[] chRtn; } + } void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr> bmpdata) @@ -435,6 +442,7 @@ bool ImageMatQueue::queuesempty() return atm_orgin_image_remains <= 0 && m_imagedata.Size() == 0; } +static int indeximg = 0; void ImageMatQueue::proc() { @@ -509,23 +517,25 @@ void ImageMatQueue::proc() else { auto mat = imread(info.path, rmc); + //cv::imwrite("D:\\img"+to_string(indeximg++)+".jpg", mat); //auto mat = imread(info.path, IMREAD_COLOR); //if (rmc == IMREAD_GRAYSCALE) // cvtColor(mat, mat, CV_RGB2GRAY); if (!mat.empty()) { - Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows)); - Mat back = mat(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows)); + Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows-10));//ͼβЧݶ10 + Mat back = mat(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows-10));//ͼβЧݶ10 #ifdef UV mats.push_back(scanParam.is_switchfrontback ? front : back); mats.push_back(scanParam.is_switchfrontback ? back : front); #else + if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) { cv::flip(front, front, 0); cv::flip(front, front, 1); } - mats.push_back(back); - mats.push_back(front); + mats.push_back(scanParam.is_switchfrontback ? front : back); + mats.push_back(scanParam.is_switchfrontback ? back : front); #endif front.release(); back.release(); @@ -558,7 +568,6 @@ void ImageMatQueue::proc() std::vector rects; std::vector angleResults; bool isDesaskew = false; - sw.reset(); for (int j = 0; j < m_iaList.size(); j++) { m_iaList[j]->apply(mats, scanParam.is_duplex); @@ -571,6 +580,7 @@ void ImageMatQueue::proc() else if (typeid(*ptr) == typeid(CImageApplyRotation)) angleResults = dynamic_cast(ptr)->angleResults(); } + #ifdef UV if (!uvmats.empty()) { diff --git a/huagao/Device/ImageMatQueue.h b/huagao/Device/ImageMatQueue.h index 62ca9173..369d6c57 100644 --- a/huagao/Device/ImageMatQueue.h +++ b/huagao/Device/ImageMatQueue.h @@ -49,17 +49,17 @@ public: } memcpy(m_data->data() + 54, colortable, 256 * 4); } - //cv::imencode(".bmp", mat, *(m_data.get())); + cv::imencode(".bmp", mat, *(m_data.get())); setBmpFileHeader(mat); setBmpInfoHeader(mat, res); - uchar* data = m_data->data() + headersize + bmpdatasize; - uchar* matdata = mat.data; - for (int i = 0; i < mat.rows; i++) { - data -= m_datalinesize; - memcpy(data, matdata, step); - matdata += step; - } + //uchar* data = m_data->data() + headersize + bmpdatasize; + //uchar* matdata = mat.data; + //for (int i = 0; i < mat.rows; i++) { + // data -= m_datalinesize; + // memcpy(data, matdata, step); + // matdata += step; + //} } private: void setBmpFileHeader(const cv::Mat& mat) @@ -90,8 +90,6 @@ private: class Mat2BmpBw :public IMat2Bmp { public: Mat2BmpBw(const cv::Mat& mat, float res) { - //static int indeximg = 0; - //cv::imwrite("D:\\" + to_string(++indeximg) + ".jpg", mat); m_data = std::shared_ptr>(new std::vector()); int headsize = 62; int width = mat.cols; diff --git a/huagao/Device/PaperSize.cpp b/huagao/Device/PaperSize.cpp index 9f80e75f..ebe609bc 100644 --- a/huagao/Device/PaperSize.cpp +++ b/huagao/Device/PaperSize.cpp @@ -24,7 +24,11 @@ namespace Device { papersize.insert({ B4,CSize(250,353) }); papersize.insert({ B5,CSize(176,250) }); papersize.insert({ B6,CSize(125,176) }); +#ifdef G400 + papersize.insert({ MaxSize,CSize(297,420 * 1.5) }); +#else papersize.insert({ MaxSize,CSize(297,420 * 2) }); +#endif papersize.insert({ USStatement,CSize(297,420 * 1.5) }); papersize.insert({ USLetter,CSize(216,279) }); papersize.insert({ USLegal,CSize(216,356) }); diff --git a/huagao/Device/PublicFunc.cpp b/huagao/Device/PublicFunc.cpp index a3fb52da..c15f7e6c 100644 --- a/huagao/Device/PublicFunc.cpp +++ b/huagao/Device/PublicFunc.cpp @@ -461,6 +461,8 @@ CString GetHidedlgPath() SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE); #ifdef MAKEHUAGAO _tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\hidedlg.exe")); +#elif defined AUGE + _tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\hidedlg.exe")); #elif defined HANVON _tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\hidedlg.exe")); #elif defined LANXUM diff --git a/huagao/Device/PublicFunc.h b/huagao/Device/PublicFunc.h index 5f24d597..f79c0bf1 100644 --- a/huagao/Device/PublicFunc.h +++ b/huagao/Device/PublicFunc.h @@ -75,6 +75,7 @@ const std::string DOCORIENTATION = "bOrientation"; const std::string AUTO_TEXT = "bAutoText"; const std::string BACKROTATE180 = "iBackRotate180"; const std::string DOGEAR_DETECTION = "dogeardetection"; +const std::string DOGEAR_DISTANCE = "idogeardistance"; const std::string SCREWDETECT = "bScrewDetect"; const std::string SCREWLEVEL = "iScrewLevel"; const std::string ITEMCAPTION = "Caption"; @@ -85,6 +86,10 @@ const std::string AUTOCROP_THRESHOLD = "AutoCrop_Threshold"; const std::string NOISE = "Noise"; const std::string LOWPOWERMODE = "ilowpowermode"; + +//twain õȲ +const std::string ROLLERMSGDATE = "RollerMsgDate"; +const std::string PRINTFCAPABILITY = "PrintfCapability"; #pragma pack(push) #pragma pack(4) /****************** @@ -257,6 +262,7 @@ struct GScanCap unsigned short scannum; /**< ɨ*/ uint8_t is_backrotate180; /**< ת180*/ uint8_t is_dogeardetection; /**<۽Ǽ*/ + uint32_t dogeardistance; /**<۽ǼⷶΧ*/ HardwareCaps hardwarecaps; /**< Ӳɨ*/ FillHole fillhole; DetachNoise detachnoise; /**< ڰ׽*/ @@ -335,6 +341,7 @@ struct GScanCap_3399 CropRect cropRect; /**< Զ>*/ MultiOutput multiOutput; /**< >*/ bool normalCrop; /**< Զɫ>*/ + uint32_t dogeardistabce; /**< ۽Ǽ۶㵽ʵ¾>*/ uint32_t reserve[1024]; /**< Ԥ4096ֽЭչ*/ }; diff --git a/huagao/Device/UsbScanEx.cpp b/huagao/Device/UsbScanEx.cpp index dc382834..9861c817 100644 --- a/huagao/Device/UsbScanEx.cpp +++ b/huagao/Device/UsbScanEx.cpp @@ -3,7 +3,320 @@ #include #include -#include "filetools.h" + +//#ifdef ANDROIDSERIAL +#if false + +UsbScanEx::UsbScanEx(int index) +{ + m_h_dev = INVALID_HANDLE_VALUE; + timeout = 100; + m_h_index = index; + CTRL_IN_OUT = 3; +} + +UsbScanEx::~UsbScanEx() +{ + if (m_h_dev != INVALID_HANDLE_VALUE) + close(); +} + +bool UsbScanEx::open() +{ + BOOL b_ret = FALSE; + TCHAR szDevPath[MAX_PATH] = { 0 }; + DWORD cbRet = 0; + + USBSCAN_TIMEOUT ut; + //ut.TimeoutEvent = 1; + //ut.TimeoutRead = 1; + //ut.TimeoutWrite = 1; + ut.TimeoutEvent = 0; + ut.TimeoutRead = 0; + ut.TimeoutWrite = 0; + + _stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), m_h_index); + m_h_dev = CreateFile(szDevPath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (m_h_dev != INVALID_HANDLE_VALUE) { + m_b_is_connected = TRUE; + b_ret = DeviceIoControl(m_h_dev, (DWORD)IOCTL_GET_PIPE_CONFIGURATION, + NULL, 0, &m_usbscan_config, sizeof(USBSCAN_PIPE_CONFIGURATION), + &cbRet, NULL); + if (b_ret && m_usbscan_config.NumberOfPipes > 0) { + for (int by_i = 0x00; (ULONG)by_i < m_usbscan_config.NumberOfPipes; by_i++) { + + TCHAR szPipePath[MAX_PATH] = { 0 }; + _stprintf(szPipePath, TEXT("\\\\.\\Usbscan%d\\%d"), m_h_index, by_i); + m_usb_pipes[by_i].pipe_info = m_usbscan_config.PipeInfo[by_i]; + m_usb_pipes[by_i].h_pipe = CreateFile(szPipePath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (m_usbscan_config.PipeInfo[by_i].PipeType == USBSCAN_PIPE_INTERRUPT) { + INT_IN = by_i; + } + else { + if (m_usbscan_config.PipeInfo[by_i].EndpointAddress & 0x80) { + BULK_IN = by_i; + } + else { + BULK_OUT = by_i; + } + } + b_ret = DeviceIoControl(m_usb_pipes[by_i].h_pipe, IOCTL_SET_TIMEOUT, &ut, sizeof(ut), NULL, 0, &cbRet, NULL); + } + } + } + else { + CloseHandle(m_h_dev); + m_h_dev = INVALID_HANDLE_VALUE; + } + //FileTools::writelog(log_lv::log_INFO,"USB Open!"); + return m_h_dev; +} + +void UsbScanEx::set_usbhotplug_callback(usbhotplug_callback callback, void* userdata) +{ + hotplug_call = callback; + usrdata = userdata; +} + +bool UsbScanEx::close() +{ + BOOL b_ret = FALSE; + BYTE by_i = 0x00; + + if (m_h_dev != INVALID_HANDLE_VALUE) { + PIPE_TYPE pipeType = ALL_PIPE; + //b_ret = DeviceIoControl(m_h_dev, (DWORD)IOCTL_RESET_PIPE, + // &pipeType, sizeof(PIPE_TYPE), NULL, 0,NULL, NULL); + BOOL bState = FALSE; + DWORD cbRet = 0; + + for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++) { + //b_ret = DeviceIoControl(m_h_dev, (DWORD)IOCTL_RESET_PIPE, + // &pipeType, sizeof(PIPE_TYPE), NULL, 0, NULL, NULL); + CloseHandle(m_usb_pipes[by_i].h_pipe); + m_usb_pipes[by_i].h_pipe = INVALID_HANDLE_VALUE; + } + b_ret = CloseHandle(m_h_dev); + + if (b_ret) { + m_h_dev = INVALID_HANDLE_VALUE; + b_ret = TRUE; + } + } + m_b_is_connected = FALSE; + //FileTools::writelog(log_lv::log_INFO,"USB Close!"); + return b_ret; +} + +void UsbScanEx::set_timeout(int timeout) +{ + this->timeout = timeout; +} + +int UsbScanEx::read_bulk(void* data, int len) +{ + BOOL b_ret = FALSE; + HANDLE h_pipe = m_usb_pipes[BULK_IN].h_pipe; + unsigned long pdw_ret = len; + if (m_h_dev != NULL) { + b_ret = ReadFile(h_pipe, data, len, &pdw_ret, NULL); + if (b_ret) { + return pdw_ret; + } + else { + int error_code = GetLastError(); + switch (error_code) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_ACCESS_DENIED: + m_b_is_connected = false; + if (hotplug_call) { + hotplug_call(true, usrdata); + } + break; + default: + break; + } + } + } + return 0; +} + +int UsbScanEx::write_bulk(void* data, int len) +{ + BOOL b_ret = FALSE; + HANDLE h_pipe = m_usb_pipes[BULK_OUT].h_pipe; + void* p_data = data; + unsigned long dw_size = len; + if (m_h_dev == INVALID_HANDLE_VALUE) + return TRUE; + b_ret = WriteFile(h_pipe, p_data, dw_size, &dw_size, NULL); + if (b_ret) { + return dw_size; + } + else { + int error_code = GetLastError(); + switch (error_code) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_ACCESS_DENIED: + m_b_is_connected = false; + if (hotplug_call) { + hotplug_call(true, usrdata); + } + break; + default: + break; + } + } + return 0; +} + +int UsbScanEx::control_msg(int rtype, int req, int value, int index, int len, void* data) +{ + BOOL b_ret = FALSE; + _IO_BLOCK_EX irp; + DWORD dw_ret; + + if (m_h_dev == INVALID_HANDLE_VALUE) + return TRUE; + irp.uOffset = value; + irp.uLength = len; + irp.uIndex = index; + irp.pbyData = (LPBYTE)data; + irp.fTransferDirectionIn = (rtype >> 7); + irp.bRequest = req; + irp.bmRequestType = (rtype >> 5) & 0x03; + + LPOVERLAPPED lp_overlap = ov + CTRL_IN_OUT; + b_ret = DeviceIoControl(m_h_dev, IOCTL_SEND_USB_REQUEST, &irp, sizeof(irp), data, len, &dw_ret, NULL); + + //if (!b_ret) + // b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0; + + return b_ret; +} + +bool UsbScanEx::is_open() +{ + return m_h_dev != INVALID_HANDLE_VALUE; +} + +bool UsbScanEx::is_connected() +{ + return is_open();//m_b_is_connected; +} + +int UsbScanEx::read_int(void* data, int len) +{ + BOOL b_ret = FALSE; + DWORD dw_ret = 0L; + HANDLE h_pipe = m_usb_pipes[INT_IN].h_pipe; + + if (m_h_dev == INVALID_HANDLE_VALUE) + return FALSE; + + b_ret = DeviceIoControl(h_pipe, (DWORD)IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, + data, len, &dw_ret, NULL); + + if (b_ret) { + return dw_ret; + } + else { + switch (GetLastError()) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_ACCESS_DENIED: + m_b_is_connected = false; + if (hotplug_call) { + hotplug_call(true, usrdata); + } + break; + default: + break; + } + } + + return 0; +} + +UsbScan_List::~UsbScan_List() +{ +} + +std::list> UsbScan_List::find_all() +{ + auto devs = find_all_usb(); + std::list> usbs; + for (auto inter = devs.begin(); inter != devs.end(); inter++) { + usbs.push_back(std::shared_ptr(new UsbScanEx(inter->index))); + } + return usbs; +} + +std::list> UsbScan_List::find_vid_pid(int vid, int pid) +{ + auto devs = find_all_usb(); + std::list> usbs; + for (auto inter = devs.begin(); inter != devs.end(); inter++) { + if (inter->vid == vid && inter->pid == pid) + usbs.push_back(std::shared_ptr(new UsbScanEx(inter->index))); + } + return usbs; +} + +std::list UsbScan_List::find_all_usb() +{ + BOOL b_ret = FALSE; + DWORD cbRet = 0; + TCHAR szDevPath[MAX_PATH] = { 0 }; + DEVICE_DESCRIPTOR dev_desc; + HANDLE h_dev; + std::list usbs; + usb_scan_dev_info dev_info; + + for (int i = 0; i < 1024; i++) { + + _stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), i); + h_dev = CreateFile(szDevPath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (h_dev != INVALID_HANDLE_VALUE) { + b_ret = DeviceIoControl(h_dev, (DWORD)IOCTL_GET_DEVICE_DESCRIPTOR, + &dev_desc, sizeof(dev_desc), &dev_desc, sizeof(dev_desc), + &cbRet, NULL); + if (b_ret != 0) { + dev_info.index = i; + dev_info.vid = dev_desc.usVendorId; + dev_info.pid = dev_desc.usProductId; + usbs.push_back(dev_info); + } + CloseHandle(h_dev); + } + } + + return usbs; +} + +#else + + UsbScanEx::UsbScanEx(int index) { @@ -154,7 +467,6 @@ int UsbScanEx::read_bulk(void* data, int len) lp_overlap->Offset = 0; lp_overlap->OffsetHigh = 0; lp_overlap->Pointer = 0; - if (m_h_dev != NULL) { b_ret = ReadFile(h_pipe, data, len, &pdw_ret, lp_overlap); //b_ret = GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); @@ -167,10 +479,12 @@ int UsbScanEx::read_bulk(void* data, int len) switch (error_code) { case ERROR_IO_PENDING: { - auto ret = WaitForSingleObject(lp_overlap->hEvent, 300); - //FileTools::writelog(log_FATAL, "WaitForSingleObject return " + std::to_string(ret));; +#ifdef ANDROIDSERIAL + GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); +#else + WaitForSingleObject(lp_overlap->hEvent, 500); GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE); - //GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); +#endif // ANDROIDSERIAL return pdw_ret; } case ERROR_FILE_NOT_FOUND: @@ -205,14 +519,15 @@ int UsbScanEx::write_bulk(void* data, int len) return dw_size; } else { - //int errorcode = GetLastError(); - //switch (errorcode) switch (GetLastError()) { case ERROR_IO_PENDING: +#ifdef ANDROIDSERIAL + GetOverlappedResult(h_pipe, lp_overlap, &dw_size, TRUE); +#else WaitForSingleObject(lp_overlap->hEvent, 500); GetOverlappedResult(h_pipe, lp_overlap, &dw_size, FALSE); - //GetOverlappedResult(h_pipe, lp_overlap, &dw_size, TRUE); +#endif // ANDROIDSERIAL return dw_size; case ERROR_FILE_NOT_FOUND: case ERROR_ACCESS_DENIED: @@ -362,3 +677,4 @@ std::list UsbScan_List::find_all_usb() return usbs; } +#endif // ANDROIDSERIAL \ No newline at end of file diff --git a/huagao/Device/UsbScanEx.h b/huagao/Device/UsbScanEx.h index 13a1b9d8..2b7e09d0 100644 --- a/huagao/Device/UsbScanEx.h +++ b/huagao/Device/UsbScanEx.h @@ -3,7 +3,7 @@ #include #include #endif // WINDOWS - +#include #include #include #include "IUsb.h" diff --git a/huagao/Device/filetools.h b/huagao/Device/filetools.h index c9a8d12f..0c5ab5f0 100644 --- a/huagao/Device/filetools.h +++ b/huagao/Device/filetools.h @@ -8,6 +8,7 @@ #include #include "PublicFunc.h" +#define enum2str(R) #R enum log_lv :int { log_TRACE = 0, diff --git a/huagao/GscanJsonConfig.cpp b/huagao/GscanJsonConfig.cpp index f8221c7c..58b63594 100644 --- a/huagao/GscanJsonConfig.cpp +++ b/huagao/GscanJsonConfig.cpp @@ -136,6 +136,7 @@ void GscanJsonConfig::SaveGscanCapConfig(const GScanCap & gcap, const std::strin outJson["Config"].Add(INDENT, (int)(gcap.indent)); outJson["Config"].Add(AUTOCROP_THRESHOLD, (int)(gcap.AutoCrop_threshold)); outJson["Config"].Add(DOGEAR_DETECTION, (bool)(gcap.is_dogeardetection), false); + outJson["Config"].Add(DOGEAR_DISTANCE, (uint32_t)(gcap.dogeardistance)); outJson["Config"].Add(SCREWDETECT, (bool)(gcap.hardwarecaps.en_skrewdetect), false); outJson["Config"].Add(SCREWLEVEL, (int)(gcap.hardwarecaps.skrewdetectlevel)); outJson["Config"].Add(ITEMCAPTION, (string)(gcap.Caption)); @@ -203,7 +204,7 @@ void GscanJsonConfig::WriteJsonArrayToFile(std::vector cfgArray, const root["Config"].AddEmptySubArray(INDENT); root["Config"].AddEmptySubArray(AUTOCROP_THRESHOLD); root["Config"].AddEmptySubArray(ISCONVEX); - + root["Config"].AddEmptySubArray(DOGEAR_DISTANCE); /*< other settings*/ root["Config"].AddEmptySubArray(ITEMCAPTION); @@ -257,6 +258,7 @@ void GscanJsonConfig::WriteJsonArrayToFile(std::vector cfgArray, const root["Config"][ISCONVEX].Add(i, (bool)cfgArray[i].is_convex); root["Config"][AUTOCROP_THRESHOLD].Add((int)cfgArray[i].AutoCrop_threshold); root["Config"][DOGEAR_DETECTION].Add(i, (bool)cfgArray[i].is_dogeardetection); + root["Config"][DOGEAR_DISTANCE].Add((int)cfgArray[i].dogeardistance); root["Config"][SCREWDETECT].Add(i, (bool)cfgArray[i].hardwarecaps.en_skrewdetect); root["Config"][SCREWLEVEL].Add((int)cfgArray[i].hardwarecaps.skrewdetectlevel); @@ -449,6 +451,8 @@ std::vector GscanJsonConfig::parseJsonFromString(const std::string str root["Config"].Get(AUTOCROP_THRESHOLD, itmAutoCrop_t); neb::CJsonObject itmdogeardetection; root["Config"].Get(DOGEAR_DETECTION, itmdogeardetection); + neb::CJsonObject itmdogdistance; + root["Config"].Get(DOGEAR_DISTANCE, itmdogdistance); neb::CJsonObject itmScrewDetct; root["Config"].Get(SCREWDETECT, itmScrewDetct); neb::CJsonObject itmScrewLevel; @@ -562,6 +566,8 @@ std::vector GscanJsonConfig::parseJsonFromString(const std::string str cfp.is_convex = b_value ? 1 : 0; itmdogeardetection.Get(i, b_value); cfp.is_dogeardetection = b_value ? 1 : 0; + itmdogdistance.Get(i, i_value); + cfp.dogeardistance = i_value; itmScrewDetct.Get(i, b_value); cfp.hardwarecaps.en_skrewdetect = b_value ? 1 : 0; itmScrewLevel.Get(i, i_value); @@ -675,6 +681,8 @@ std::vector GscanJsonConfig::parseJsonFromString(const std::string str cfp.is_convex = bvalue ? 1 : 0; root["Config"].Get(DOGEAR_DETECTION, bvalue); cfp.is_dogeardetection = bvalue ? 1 : 0; + root["Config"].Get(DOGEAR_DISTANCE, index); + cfp.dogeardistance = index; root["Config"].Get(SCREWDETECT, bvalue); cfp.hardwarecaps.en_skrewdetect = bvalue ? 1 : 0; root["Config"].Get(SCREWLEVEL, index); @@ -757,6 +765,7 @@ json GscanJsonConfig::GscancapToJson(GScanCap& cap) js[CONFIG][AUTO_TEXT] = cap.is_autotext; js[CONFIG][BACKROTATE180] = cap.is_backrotate180; js[CONFIG][DOGEAR_DETECTION] = cap.is_dogeardetection; + js[CONFIG][DOGEAR_DISTANCE] = cap.dogeardistance; js[CONFIG][SCREWDETECT] = cap.hardwarecaps.en_skrewdetect; js[CONFIG][SCREWLEVEL] = cap.hardwarecaps.skrewdetectlevel; js[CONFIG][NOISE] = cap.noise; @@ -815,6 +824,7 @@ GScanCap GscanJsonConfig::JsonToGscancap(json& js) cap.is_autotext = json_cast(js[CONFIG][AUTO_TEXT]).to_int(); cap.is_backrotate180 = json_cast(js[CONFIG][BACKROTATE180]).to_int(); cap.is_dogeardetection = json_cast(js[CONFIG][DOGEAR_DETECTION]).to_int(); + cap.dogeardistance = json_cast(js[CONFIG][DOGEAR_DISTANCE]).to_uint32(); cap.hardwarecaps.en_skrewdetect = json_cast(js[CONFIG][SCREWDETECT]).to_int(); cap.hardwarecaps.skrewdetectlevel = json_cast(js[CONFIG][SCREWLEVEL]).to_int(); cap.noise = json_cast(js[CONFIG][NOISE]).to_int(); @@ -869,6 +879,7 @@ json GscanJsonConfig::GetDefaultJson() "bAutoText": false , "iBackRotate180": false , "dogeardetection": false , + "idogeardistance": 50 , "bScrewDetect": true , "iScrewLevel": 3 , "Noise": 8 , @@ -920,6 +931,7 @@ json GscanJsonConfig::GetDefaultJson() "bAutoText": false , "iBackRotate180": false , "dogeardetection": false , + "idogeardistance": 50 , "bScrewDetect": true , "iScrewLevel": 3 , "Noise": 8 , @@ -955,3 +967,97 @@ json GscanJsonConfig::Readjson(std::string path) return GetDefaultJson(); } } + +Twain_config::Twain_config() +{ +} + +Twain_config::~Twain_config() +{ +} + +int Twain_config::getrollermsgdate() +{ + loadjson(GetTwainInIPath() + TCHAR2STRING(TWAIN_CONFIG_JSON)); + if (m_json[ROLLERMSGDATE].is_null()) + return 0; + int date = 0; + m_json[ROLLERMSGDATE].get_to(date); + return date; +} + +void Twain_config::GetOrSetPintfCapability(int& value,bool is_get) +{ + loadjson(GetTwainInIPath() + TCHAR2STRING(TWAIN_CONFIG_JSON)); + if (is_get) { + if (m_json[PRINTFCAPABILITY].is_null()) { + value = 0; + return; + } + m_json[PRINTFCAPABILITY].get_to(value); + } + else{ + m_json[PRINTFCAPABILITY] = value; + savejson(m_json, GetTwainInIPath() + TCHAR2STRING(TWAIN_CONFIG_JSON)); + } +} + +void Twain_config::setrollermsgdata(int value) +{ + loadjson(GetTwainInIPath() + TCHAR2STRING(TWAIN_CONFIG_JSON)); + m_json[ROLLERMSGDATE] = value; + savejson(m_json, GetTwainInIPath() + TCHAR2STRING(TWAIN_CONFIG_JSON)); +} + +std::string Twain_config::GetTwainInIPath() +{ + TCHAR szIniFile[MAX_PATH] = { 0 }; + SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_LOCAL_APPDATA, TRUE); + _tcscat(szIniFile, HUAGAO_SCAN); + _tcscat(szIniFile, TWAIN_INIPATH); + _tcscat(szIniFile, TEXT("\\")); + return TCHAR2STRING(szIniFile); +} + +void Twain_config::savejson(json js, std::string path) +{ + std::ofstream of(path); + if(of.is_open()) + { + of.write(js.dump().data(), js.dump().size()); + of.close(); + } + else{ + FileTools::writelog(log_ERROR, "save json error "); + } +} +json Twain_config::loadjson(std::string path) +{ + std::ifstream f; + f.open(path, std::ios::in | std::ios::binary); + json js; + try { + if (f.is_open()) { + std::string text = (std::ostringstream() << f.rdbuf()).str(); + js = json::parse(text); + f.close(); + } + m_json = js; + return js.is_object() ? js : throw std::exception("js pares error"); + } + catch (...) + { + FileTools::writelog(log_ERROR, "read json error"); + f.is_open() ? f.close() : void(); + m_json = defaultjson(); + return m_json; + } +} + +json Twain_config::defaultjson() +{ + json tmp; + tmp[ROLLERMSGDATE] = 0; + tmp[PRINTFCAPABILITY] = 0; + return tmp; +} \ No newline at end of file diff --git a/huagao/GscanJsonConfig.h b/huagao/GscanJsonConfig.h index 41722a9d..daac2c24 100644 --- a/huagao/GscanJsonConfig.h +++ b/huagao/GscanJsonConfig.h @@ -97,5 +97,23 @@ public: json Readjson(std::string path); void SaveGscancapJson(GScanCap cap, std::string path); GScanCap JsonToGscancap(json& js); + +}; + +class Twain_config +{ +public: + Twain_config(); + ~Twain_config(); + int getrollermsgdate(); + void setrollermsgdata(int value); + void GetOrSetPintfCapability(int& value,bool is_get); + +private: + std::string GetTwainInIPath(); + json loadjson(std::string path); + void savejson(json js, std::string path); + json defaultjson(); + json m_json; }; diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.cpp b/huagao/ImageProcess/ImageApplyAutoCrop.cpp index 45af1f28..430b4ab6 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.cpp +++ b/huagao/ImageProcess/ImageApplyAutoCrop.cpp @@ -53,7 +53,6 @@ cv::Mat concatenateMatrix(const cv::Mat& first, const cv::Mat& second) return mul_r; } - std::vector comMat() { std::vector mats; @@ -61,14 +60,9 @@ std::vector comMat() srcTri[0] = cv::Point2f(1, 1); srcTri[1] = cv::Point2f(1, 0); srcTri[2] = cv::Point2f(0, 1); - const float fact = 0.1f; - - float pos[] = { 0, 2 * fact, fact }; + const float fact = 0.33f; + float pos[] = { 0, 2 * fact, fact }; cv::Point2f dstTri[3]; - dstTri[0] = cv::Point2f(1, 1); - dstTri[1] = cv::Point2f(1, 0.5); - dstTri[2] = cv::Point2f(0, 1); - for (int i = 0; i < 3; i++) { dstTri[0] = cv::Point2f(1, 1 + pos[i]); @@ -123,8 +117,15 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) 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::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; @@ -134,7 +135,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) if (m_maxContour.size() == 0) { thre.release(); - //����ǹ̶����棬�뷵�ز��к�ijߴ� + // 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 @@ -142,6 +143,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) #endif // LOG return; } + thre.release(); dst.release(); @@ -178,18 +180,15 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) auto mats = comMat(); warp_mat = cv::getAffineTransform(srcTri, dstTri); warp_mat = concatenateMatrix(mats[0], warp_mat); - //warp_mat = mats[0]; 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); - //warp_mat = mats[1]; 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); - //warp_mat = mats[2]; cv::warpAffine(bgr[2], bgr[2], warp_mat, rect.size, cv::INTER_LINEAR); cv::merge(bgr, 3, dst); @@ -208,6 +207,13 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) 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 { @@ -219,45 +225,31 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) 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) { - cv::Mat thre_dst; - hg::threshold_Mat(dst, thre_dst, m_threshold); - - if (m_indent > 0) - { - for (size_t i = 0, length = m_maxContour.size() - 1; i < length; i++) - cv::line(thre_dst, m_maxContour[i], m_maxContour[i + 1], cv::Scalar::all(0), m_indent * 2); - cv::line(thre_dst, *m_maxContour.begin(), *m_maxContour.rbegin(), cv::Scalar::all(0), m_indent * 2); - } - - //cv::imwrite("abc.jpg", thre_dst); - hierarchy.clear(); - contours.clear(); - m_maxContour.clear(); - hg::findContours(thre_dst, contours, hierarchy, cv::RETR_EXTERNAL); if (m_isConvexHull) { - m_maxContour = hg::getMaxContour(contours, hierarchy); - if (m_maxContour.size() == 0) { thre.release(); - //����ǹ̶����棬�뷵�ز��к�ijߴ� + 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; } hg::convexHull(m_maxContour, m_maxContour); @@ -306,8 +298,6 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) #endif // LOG } - - void CImageApplyAutoCrop::apply(std::vector& mats, bool isTwoSide) { if (mats.empty()) return; diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.h b/huagao/ImageProcess/ImageApplyAutoCrop.h index eaf84f89..e1f1f4ae 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.h +++ b/huagao/ImageProcess/ImageApplyAutoCrop.h @@ -5,13 +5,24 @@ * 作者:刘丁维 * 生成时间:2020/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 增加功能,可识别文稿颜色进行填充黑底。 - * 版本号:v1.3.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 * ==================================================== */ @@ -58,7 +69,7 @@ public: double threshold() { return m_threshold; } - const cv::RotatedRect& rotatedROI() { return m_rect; } + cv::RotatedRect& rotatedROI() { return m_rect; } const std::vector& rotatedROIs() { return m_rects; } diff --git a/huagao/ImageProcess/ImageApplyBWBinaray.cpp b/huagao/ImageProcess/ImageApplyBWBinaray.cpp index 7995a25a..ff499094 100644 --- a/huagao/ImageProcess/ImageApplyBWBinaray.cpp +++ b/huagao/ImageProcess/ImageApplyBWBinaray.cpp @@ -37,6 +37,7 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side) //20.12.29 ޸IJΪ51 10 30 235 //20.12.30 ޸IJΪ51 20 30 235 + // 꾢ڰ 51 41 30 245 // ޸IJΪ17 20 110 235 cv::Mat integ; int blockSize = 17;//ߴ diff --git a/huagao/ImageProcess/ImageApplyDogEarDetection.cpp b/huagao/ImageProcess/ImageApplyDogEarDetection.cpp index 40ef3a75..3957467d 100644 --- a/huagao/ImageProcess/ImageApplyDogEarDetection.cpp +++ b/huagao/ImageProcess/ImageApplyDogEarDetection.cpp @@ -2,19 +2,19 @@ #include "ImageProcess_Public.h" CImageApplyDogEarDetection::CImageApplyDogEarDetection() - : m_threshold(40) - , m_zoom(1.0) - , m_distance(50) - , m_result(false) + : m_threshold(40) + , m_zoom(1.0) + , m_distance(50) + , m_result(false) { } CImageApplyDogEarDetection::CImageApplyDogEarDetection(double threshlod, double zoom, double distance) - : m_threshold(threshlod) - , m_zoom(zoom) - , m_distance(distance) - , m_result(false) + : m_threshold(threshlod) + , m_zoom(zoom) + , m_distance(distance) + , m_result(false) { } @@ -24,44 +24,49 @@ CImageApplyDogEarDetection::~CImageApplyDogEarDetection() } -void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side) +void CImageApplyDogEarDetection::apply(cv::Mat& pDib, int side) { - m_result = false; - (void)side; - if (pDib.empty()) return; - cv::Mat src; - if (m_zoom != 1.0) - cv::resize(pDib, src, cv::Size(), m_zoom, m_zoom, cv::INTER_NEAREST); - else - src = pDib; + m_result = false; + (void)side; + if (pDib.empty()) return; + cv::Mat src; + if (m_zoom != 1.0) + cv::resize(pDib, src, cv::Size(), m_zoom, m_zoom, cv::INTER_NEAREST); + else + src = pDib; - cv::Mat thre; - hg::threshold_Mat(src, thre, m_threshold); - std::vector hierarchy; - std::vector> contours; - hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); + cv::Mat thre; + hg::threshold_Mat(src, thre, m_threshold); - std::vector maxContour = hg::getMaxContour(contours, hierarchy); - if (maxContour.size() == 0) - { - m_result = true; - return; - } - hg::convexHull(maxContour, maxContour); - cv::RotatedRect rect = hg::getBoundingRect(maxContour); - cv::Point2f vertexes[4]; - rect.points(vertexes); + cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(20, 1)); + cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); - for (int i = 0; i < 4; i++) - if ((-cv::pointPolygonTest(maxContour, vertexes[i], true)) > (m_distance * m_zoom)) - { - m_result = true; - return; - } + std::vector hierarchy; + std::vector> contours; + hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); + + std::vector maxContour = hg::getMaxContour(contours, hierarchy); + if (maxContour.size() == 0) + { + m_result = true; + return; + } + hg::convexHull(maxContour, maxContour); + cv::RotatedRect rect = hg::getBoundingRect(maxContour); + cv::Point2f vertexes[4]; + rect.points(vertexes); + + for (int i = 0; i < 4; i++) + if ((-cv::pointPolygonTest(maxContour, vertexes[i], true)) > (m_distance * m_zoom)) + { + m_result = true; + return; + } } -void CImageApplyDogEarDetection::apply(std::vector &mats, bool isTwoSide) +void CImageApplyDogEarDetection::apply(std::vector& mats, bool isTwoSide) { - (void)mats; - (void)isTwoSide; + (void)mats; + (void)isTwoSide; } + diff --git a/huagao/ImageProcess/ImageApplyDogEarDetection.h b/huagao/ImageProcess/ImageApplyDogEarDetection.h index a05f313c..a1516937 100644 --- a/huagao/ImageProcess/ImageApplyDogEarDetection.h +++ b/huagao/ImageProcess/ImageApplyDogEarDetection.h @@ -4,8 +4,9 @@ * 功能:折角检测。检测原理:计算纸张的理论四角顶点,到实际轮廓最小距离。当任意顶点到轮廓最小距离超过阈值,则判定为折角 * 作者:刘丁维 * 生成时间:2020/10/30 - * 最近修改时间:2020/10/30 - * 版本号:v1.0 + * 最近修改时间:2020/10/30 v1.0 + * 2021/11/04 v1.1 增加背景抗噪机制,能够抗5像素的背景噪声 + * 版本号:v1.1 * ==================================================== */ @@ -15,7 +16,7 @@ #include "ImageApply.h" -class CImageApplyDogEarDetection :public CImageApply +class CImageApplyDogEarDetection : public CImageApply { public: @@ -31,7 +32,7 @@ public: /// 原图缩放比例,对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放) /// 理论顶点到实际轮廓最小距离的阈值,大于该阈值则判定为折角,默认值50(像素) CImageApplyDogEarDetection(double threshlod, double zoom = 1.0, double distance = 50); - + void setdistance(double distance) { m_distance = distance; } virtual ~CImageApplyDogEarDetection(void); /// @@ -54,3 +55,4 @@ private: }; #endif // IMAGE_APPLY_DOGEAR_DETECTION_H + diff --git a/huagao/ImageProcess/ImageApplyOutHole.cpp b/huagao/ImageProcess/ImageApplyOutHole.cpp index 800e436d..e3e2a748 100644 --- a/huagao/ImageProcess/ImageApplyOutHole.cpp +++ b/huagao/ImageProcess/ImageApplyOutHole.cpp @@ -1,15 +1,19 @@ #include "ImageApplyOutHole.h" #include "ImageProcess_Public.h" -CImageOutHole::CImageOutHole(void) +#ifdef LOG +#include "Device/filetools.h" +#endif // LOG + +CImageApplyOutHole::CImageApplyOutHole(void) : CImageApply() - , m_borderSize(200) + , m_borderSize(600) , m_edgeScale(0.1f) - , m_threshold(50) + , m_threshold(100) { } -CImageOutHole::CImageOutHole(float borderSize, float edgeScale, double threshold) +CImageApplyOutHole::CImageApplyOutHole(float borderSize, float edgeScale, double threshold) : CImageApply() , m_borderSize(borderSize) , m_edgeScale(edgeScale) @@ -17,26 +21,35 @@ CImageOutHole::CImageOutHole(float borderSize, float edgeScale, double threshold { } -CImageOutHole::~CImageOutHole(void) +CImageApplyOutHole::~CImageApplyOutHole(void) { } -void CImageOutHole::apply(cv::Mat& pDib, int side) +void CImageApplyOutHole::apply(cv::Mat& pDib, int side) { - (void)pDib; - (void)side; + (void)pDib; + (void)side; } -void CImageOutHole::apply(std::vector& mats, bool isTwoSide) +void CImageApplyOutHole::apply(std::vector& mats, bool isTwoSide) { +#ifdef LOG + FileTools::write_log("imgprc.txt", "enter ImageOutHole apply"); +#endif // LOG if (mats.size() < 2) { +#ifdef LOG + FileTools::write_log("imgprc.txt", "exit ImageOutHole apply"); +#endif // LOG return; } if (mats[0].empty() || mats[1].empty()) { +#ifdef LOG + FileTools::write_log("imgprc.txt", "exit ImageOutHole apply"); +#endif // LOG return; } @@ -47,6 +60,10 @@ void CImageOutHole::apply(std::vector& mats, bool isTwoSide) hg::threshold_Mat(front, front_thre, m_threshold); hg::threshold_Mat(back, back_thre, m_threshold); + cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(10, 1)); + cv::morphologyEx(front_thre, front_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); + cv::morphologyEx(back_thre, back_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); + //ֵͼˮƽת cv::flip(back_thre, back_thre, 1); //1:Horizontal @@ -63,6 +80,11 @@ void CImageOutHole::apply(std::vector& mats, bool isTwoSide) cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //ȡСӾ cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //ȡСӾ + //ͼߴ쳬20أֱӷ + if (cv::abs(rrect_front.size.width - rrect_back.size.width) > 20 || + cv::abs(rrect_front.size.height - rrect_back.size.height) > 20) + return; + //ȡͼص cv::Rect roi_front, roi_back; cv::RotatedRect mask_rotatedRect; @@ -73,56 +95,61 @@ void CImageOutHole::apply(std::vector& mats, bool isTwoSide) //ֵͼ㣬ο0طΪ255 cv::Mat mask; - bitwise_or(roiMat_front, roiMat_back, mask); //㣬ֵͼص + cv::bitwise_or(roiMat_front, roiMat_back, mask); //㣬ֵͼص + + cv::imwrite("roiMat_front.jpg", roiMat_front); + cv::imwrite("roiMat_back.jpg", roiMat_back); //ֵͼصͼɫȡͣȡ - std::vector> contours_mask; - std::vector b1_mask; - bitwise_not(mask, mask); //ɫ + cv::bitwise_not(mask, mask); //ɫ - cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(15, 15)); - dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //㷨׶ͨ + element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10)); + cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //㷨׶ͨ //Ϊ˱׶׹ᴩֽߣΪֽȷп׶ΪͼΣ뱳ճ - polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //ֽžαԵ + cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //ֽžαԵ - hg::findContours(mask.clone(), contours_mask, b1_mask, cv::RETR_TREE); //ȡصͼ + std::vector> contours_mask; + std::vector b1_mask; + hg::findContours(mask, contours_mask, b1_mask, cv::RETR_TREE); //ȡصͼ //˷ǿ׶ͨ std::vector> hole_contours = filterPoly(contours_mask, b1_mask, mask_rotatedRect, m_edgeScale, m_borderSize); - for (size_t i = 0; i < hole_contours.size(); i++) - cv::drawContours(mask, hole_contours, static_cast(i), cv::Scalar(127), 2); - + //for (size_t i = 0; i < hole_contours.size(); i++) + // cv::drawContours(mask, hole_contours, static_cast(i), cv::Scalar(127), 2); + //cv::imwrite("mask.jpg", mask); + cv::Scalar color = getBackGroudColor(front(roi_front), rrect_front.size.area()); for (size_t i = 0; i < hole_contours.size(); i++) { - cv::Scalar color = getBackGroudColor(front(roi_front), hole_contours[i]); - cv::Mat temp = front(roi_front); std::vector> contourss_temp; contourss_temp.push_back(hole_contours[i]); - hg::fillPolys(temp, contourss_temp, color); + cv::Mat front_temp = front(roi_front); + hg::fillPolys(front_temp, contourss_temp, color); } if (isTwoSide) { int width_ = roi_back.width; roi_back.x = back.cols - roi_back.width - roi_back.x; //Ϊ֮ǰͼתROIҲҪӦת + color = getBackGroudColor(back(roi_back), rrect_front.size.area()); for (size_t i = 0; i < hole_contours.size(); i++) { std::vector hole_contour; for (size_t j = 0; j < hole_contours[i].size(); j++) hole_contour.push_back(cv::Point(width_ - hole_contours[i][j].x - 1, hole_contours[i][j].y)); - cv::Scalar color = getBackGroudColor(back(roi_back), hole_contour); - cv::Mat temp = back(roi_back); - std::vector> contours_temp; contours_temp.push_back(hole_contour); - hg::fillPolys(temp, contours_temp, color); + cv::Mat back_temp = back(roi_back); + hg::fillPolys(back_temp, contours_temp, color); } } +#ifdef LOG + FileTools::write_log("imgprc.txt", "exit ImageOutHole apply"); +#endif // LOG } -void CImageOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, +void CImageApplyOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front, cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect) { cv::Size size(static_cast(rrect_front.size.width + rrect_back.size.width) / 2, static_cast(rrect_front.size.height + rrect_back.size.height) / 2); @@ -180,7 +207,7 @@ void CImageOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_ba mask_rotatedRect.angle = angle; } -std::vector> CImageOutHole::filterPoly(std::vector>& contours, const std::vector& m, +std::vector> CImageApplyOutHole::filterPoly(std::vector>& contours, const std::vector& m, cv::RotatedRect roi, float edgeScale, float areaThreshold) { edgeScale = std::min(0.49f, std::max(edgeScale, 0.0f)); @@ -196,7 +223,7 @@ std::vector> CImageOutHole::filterPoly(std::vector areaThreshold || rrect.size.height > areaThreshold) continue; + if (rrect.size.area() < areaThreshold) continue; bool enabled = true; for (size_t j = 0, count = contours[i].size(); j < count; j++) @@ -218,7 +245,7 @@ std::vector> CImageOutHole::filterPoly(std::vector pixelPoints) +cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, const std::vector pixelPoints) { if (pixelPoints.empty()) return cv::Scalar(255, 255, 255); @@ -235,7 +262,62 @@ cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vec temp[j] += ptr[j]; } - return cv::Scalar(temp[0] / static_cast(pixelPoints.size()), - temp[1] / static_cast(pixelPoints.size()), - temp[2] / static_cast(pixelPoints.size())); + return cv::Scalar(temp[0] / static_cast(pixelPoints.size()), + temp[1] / static_cast(pixelPoints.size()), + temp[2] / static_cast(pixelPoints.size())); } + +cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, int total) +{ + 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); + return cv::Scalar(bgr[0], bgr[1], bgr[2]); + } + else + return cv::Scalar::all(getBackGroudChannelMean(image, total)); +} + +uchar CImageApplyOutHole::getBackGroudChannelMean(const cv::Mat& gray, int total) +{ + cv::Mat image_clone; + cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25); + + int threnshold = total / 32; + int channels[] = { 0 }; + int nHistSize[] = { 256 }; + float range[] = { 0, 256 }; + const float* fHistRanges[] = { range }; + cv::Mat hist; + cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, nHistSize, fHistRanges, true, false); + + int hist_array[256]; + for (int i = 0; i < 256; i++) + hist_array[i] = hist.at(i, 0); + + int length = 1; + const int length_max = 255 - m_threshold; + while (length < length_max) + { + for (size_t i = m_threshold + 1; i < 256 - length; i++) + { + int count = 0; + uint pixSum = 0; + for (size_t j = 0; j < length; j++) + { + count += hist_array[j + i]; + pixSum += hist_array[j + i] * (i + j); + } + + if (count >= threnshold) + return pixSum / count; + } + length++; + } + return 255; +} \ No newline at end of file diff --git a/huagao/ImageProcess/ImageApplyOutHole.h b/huagao/ImageProcess/ImageApplyOutHole.h index 9ed49b3f..0b412861 100644 --- a/huagao/ImageProcess/ImageApplyOutHole.h +++ b/huagao/ImageProcess/ImageApplyOutHole.h @@ -1,18 +1,39 @@ +/* + * ==================================================== + + * ܣװ + * ߣά + * ʱ䣺2020/11/21 + * ޸ʱ䣺2020/05/12 v1.0 + * 2020/11/17 v1.1 + * 2021/09/06 v1.2 Ĭ϶ֵֵԭ50Ϊ100ɫӾֲɫȡΪȫɫȡ + * 2021/11/03 v1.3 ߼ͼߴ쳬10أֱӷأٽг״ + * 2021/11/04 v1.4 ӱƣܹ5صı + * 2021/11/17 v1.5 ʽһЩopencv汾µBUG + * 汾ţv1.5 + + * ==================================================== + */ + #ifndef IMAGE_APPLY_OUT_HOLE_H #define IMAGE_APPLY_OUT_HOLE_H #include "ImageApply.h" -class CImageOutHole : public CImageApply +class CImageApplyOutHole : public CImageApply { - public: - CImageOutHole(); + CImageApplyOutHole(); - CImageOutHole(float borderSize, float edgeScale, double threshold); + /* + * borderSize [in]:׶ֵ + * edgeScale [in]:ֽűԵȡֵΧ(0,0.5),Ĭֵ0.1 + * threshold [in]:ֵֵ + */ + CImageApplyOutHole(float borderSize, float edgeScale, double threshold); - ~CImageOutHole(void); + ~CImageApplyOutHole(void); virtual void apply(std::vector& mats, bool isTwoSide); @@ -26,7 +47,7 @@ public: void setEdgeScale(float scale) { m_edgeScale = scale; } - void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); } + void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); } private: @@ -35,15 +56,20 @@ private: void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front, cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect); - std::vector > filterPoly(std::vector>& contours, const std::vector &m, cv::RotatedRect roi, + std::vector > filterPoly(std::vector>& contours, const std::vector& m, cv::RotatedRect roi, float edgeScale, float areaThreshold); cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector pixelPoints); + cv::Scalar getBackGroudColor(const cv::Mat& image, int total); + + uchar getBackGroudChannelMean(const cv::Mat& gray, int total); + private: float m_borderSize; float m_edgeScale; double m_threshold; }; -#endif // !IMAGE_APPLY_OUT_HOLE_H \ No newline at end of file +#endif // !IMAGE_APPLY_OUT_HOLE_H + diff --git a/huagao/ImageProcess/ImageApplyUV.cpp b/huagao/ImageProcess/ImageApplyUV.cpp index 56808fe6..cd8214b6 100644 --- a/huagao/ImageProcess/ImageApplyUV.cpp +++ b/huagao/ImageProcess/ImageApplyUV.cpp @@ -97,7 +97,6 @@ cv::Mat ImageApplyUV::Apply(const cv::Mat& image, const cv::Mat& uv, const cv::R cv::Mat uv_temp; cv::warpAffine(uv, uv_temp, warp_mat, cv::Size(uvRoi_clone.size.width, uvRoi_clone.size.height)); - //cv::imwrite("uv_temp.jpg", uv_temp); if (pixtype == 0)//ֵͼ { cvtColor(uv_temp, uv_temp, cv::COLOR_BGR2GRAY); @@ -201,7 +200,6 @@ cv::Mat ImageApplyUV::Apply(const cv::Mat& image, const cv::Mat& uv, const cv::R } uv_roi.copyTo(dst_uv(cv::Rect((dst_uv.cols - uv_roi.cols + offset_left) / 2, (dst_uv.rows - uv_roi.rows + offset_top) / 2, uv_roi.cols, uv_roi.rows))); } - //imwrite("D:\\dst" + std::to_string(svindex) + ".jpg", dst); return dst; } diff --git a/huagao/auge_logo.bmp b/huagao/auge_logo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bc4172fac68b009a8c0d2d720f3baaafef3d605a GIT binary patch literal 162054 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 literal 0 HcmV?d00001 diff --git a/huagao/auge_logo1111.bmp b/huagao/auge_logo1111.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e797f8360f1e1903f5faa625fda16d27d7050a4a GIT binary patch literal 105894 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

CCOVu<=X2ASTwIbKVsYs_(?S0^ zxReAg-DFy~E$)s>O$BQLAI`Vyu3i638@w4ozm**?KTQqepnUaM5r zTh60kph0wMPdsn2#bGBN1q`a%!?ok+g;Fz`NX_T+FGk~zaam>KiLd))K@0ONb7IQoef)cE-hb~Prbc_i`sj1J z9@xr9WNIcl0=B2-3XaYKKf^OK!V^Dg6lKg&lPHWl?tjCPimxvPxmCyCs+yBrs=gw-{y2O-BAA`OLHi?JP?-hp~o=M!x6!tuZ|KxAA>tDg3 zz*4^JIQK!j=fC#3&>q|Jq2*5*!~RTDXPUyje=EAmj%%2uwIGc9C|&fe00)-_qA$hv z%~_xS4R!m5?f2a)v&yxf4{egot$599@VRx{5@T}SiNTqs?21hEiq5`k+Kl?=3)oMW%@M;!(*__)=rg2M(9B$5PGu znI!|Or^Tg?8u^zjF2UF2Z^wst9^FIV0VtevKmMgXp3hBR0+;mtMy+kMxJ2Js{}OZ& zztzp?iA%&)wpJ%M9a@JSq;K2Ej>9)8-?!CA!6x$1I_^q**rqBQ!4v-Zz-ZG~pAN;n zn#VL3u5~C{w=4a(CoX9YT6+}~Ypp8wULIp#^XMm-PtS#4m9%$-cy}=AAoKG(Q*TK= zE4l=ZtTlOM*9J>cLH7_#7@{Z;EGUrOFzN7??SO&?61*EIJR@S6Gu-nBR)e}S;q z@hfZoLVNCpcT7j$dChniKFDvycY`(TDQvdPWlSFa6SvMiaYMmJFJ+vN^@*u ztSx78sUuKga;DyA=f-TT0X!^Rk{&OAw-0@xh;_}T=1@sDnw$|!9bBsYB5^4iClD8x z)F;rTb}G2EJ=TuX-g3TVAA3UQ&A1a;5P3kNEsEIuW)HK^H@&&k{jdg=su1PB!62IvG68TNTLamXlkkCJeqVK``f+VuVXdp zd~Nc;cqX2!Ns1?~RB4l$UeS6-!SGmY@lGO;vCTtzzX^EedzxB z-ew`87cEVBbex^f{O`~}bZ}`r(BmJQwz_#8dzcbM-Ze{3{zztmg3 zza+Ty@f_^9IQkO(sQI{h`Ioxkl4Nl3l3>~1+%jTx_5GAEa<)zM)Lbk{x}NsxEMJ_f=84;sgJpG0L&ya^Y?H_Qiwh&sdvGGPds2I+X8HXQgjN+wi9`=L6-( zp?f}%4=zn-Y~o{pmnARdODT`yQdaVvQ+ABIt^G5;t+tQ2COsz~k=9Dd2k5Njm5&wu z-}+5iM@7HuyOq)*_Uq~=!R;Zn=K)!Bz<-OV@TwNDH-E^{hg>}>6Y z>1VxJD|=McLYHjzKMZ+xNuFqK+_4o0k4xxG!7&}dd~|8kIgqer#id|9c z1>c(CTSGp_mdp90&OrGuo0h#`byMyA@2<7C`y}yObJ<0F7sr%rjrU#eGw|P+2$zsa zilG$V+PxJxO1`+b)Ur+frPzJp6k|{l416@->cwt+fno)0oFjUu=JXYhQo^@ZS+UrzO6Bf!1e`&x1?l z;F7-WrM=A*j}yhEy_M^yUy{#!Tm|bjYBaZro+1CW=B3p>>4H= zV>x=L^vSk!hrl);NZ&7I-`qwNj+5H5*+_+S+5q*g`0pXJNLaL@8 zJ$z%e=FRDkEUGs6&i8`n(8yE9m;rEt*$=Y%HmZoFRNMGv0CCN(K*tUIXOq_tl zrT?J+%iAim!?jDFL}wy?LYO`N=ioJZFZQ|Cq6FY=tph4w{1_xX2zdfq=}-9awEpP@ zKR&PLqIMj(ovHqnitsSTNWqlXi^U|XgHE&J7 zZEwo$GY+QQVCRzco!AP-y4LI~);yOu#3F1T?Rnn}P6?Z2g9qqKt!X&Myi_jngu*<< zG?nuH3GBLk_jHGbgDKaU=E9xvaS578_h>_Q zYM;8+t*ARWn~{+&f7NB1iXEnqHT02fbMUPdajW^<;`D2?wWeNsuxameyYI%EV+kuL zU_5w}c<5|#3BIrU)060ofmP!yW;US@$meJGwU&H`7psK3`eq7ytar5JnOtHTh0As= z1buFO-SnMwOvUfz&$%C4vjSR#ell>q?#qHpPMknbT#{^&PrnxV)pDA?WU=WozGLX~ z9{a4rO9^kx$?@3g>t1(`CgigPS{`@bt+g$#0kFmI<^~(5H zsK0|tifw~`>0f;h<;%2>?x}GUZ3nniNxXL{ww0g0lCGmYC|q1J^~e9GX+E^V`1i6$ z;Sv*Ac#nx}cn1Dnk677-&*D>4k6&9DtnWg%*zw0W{BS(OrnxJ`Ly!L}c?yqNQ zU(rV9p?8q*8PzhS+m&cbZER9IJ~4s!Czxlk6V7 z8)9vd_)~sHt&Pxr&5h{W)x?blwl0EHjWAhow|k5(c(kH;HR~=s;B6IqYK5|3+lH;i zvp$)1_N^5mTABqtV36l9T-?J#&i^ZM3y!8^6wAf`@e{+&sfvQ zzJapw?7BkU*BYXJ#R;&lavi?0TGpJ{Z?NFg)_%B6!~@o_uSn$JV%X%!ljtpfep3!KJC$SJ70e;yM6+D6hK>HzG5tD=HA6L+7Xn0@Bi+- zUj4=cd`#wV@iSfA(NbaZ7CgpULwy&CzQCuY_+G^;_$k|qF6p0kwdq{_IQs0RcJ9Ji zuf~|8U4H1NZ>1fbem7kn@B2&rt&@XGr{XHVC_ApZzH~Y+-Dn~^V&ep2+ZVjVwAI%8 z54_D<1^k3jnJr&r5MIzaAMNohOqVaiGyP7}xcv>fq6t5^_JR4L;+hmE!2VI-lARZ4 zJe|^)q(lFX*m1ri;L;@4dO7P|HBY5@$qMkKYTYcxwEfQ9H`+d6o!ra6L@#0A8u~?R z(CXRW_+$xjeQ&1X;{}&wJD^YKJFKCsS4_)+O~%9eLVaIW`@hSEX<$uC%l6kFA>Thj zq4`$ut@Ks(GjHJ?>_6~CzVnKd{>6KjZ-0Be_GM7)u%GXD*fq7(!OuK>9d)c=-><;I zw_e4j`d^gSi`;KvG2p@DW$d$6j$V_;8ox^RFm0>P;g#kDvwKNa<-9S(`09JBtfd%F z90ReXt&)$$+t_F6Ip&Nl?*Ilf-c`WaNqhdwt@zmi+$F9|NO&q)dMIga03{w-&1nDnJ)_@id} zjV9bHE_pA42IZz9FYJGNlJ#9`Z&te}G#IbEv=+HT=kTuegHOc|zU38TBBcnd07UGD zP2WTgeS3)dyBA&-{T+SjIB^16pCnnRG3EM~B(LOKb@r=_>-YYW#0g->X?+~HB;8c| z*f%lmD)~-z)tj>(vvh1a^3O%{9^9xsZWWW=#P?A0C;Y-Rf;%QsHYPje#w8_SgPrHc z&sv>4iu|q~qj!tu-M_>$Wweb?(tK^X@NdHe4{?6i=ziqQlqHRGZnwB(*X>fijrX?k zOJ~?mz+1Y$e8Vj2asybZZ*4i>64JU_?Ij{#bp_uI@EzQchT--j&G`r}53)dx^Ea8vnl5 z{b>)%i|pQmUgBCh%J<#{kNk<*Ixo9w`Yq7(Vz2>y1>7z|zl)R$mqPzeJ-&LXK5o4R zeEbT|0(|J`OrbLNpS+#=5W@{N+4ZKhOY4i=7y!G^I(=>T*U-2^=4+fupDLPyid?j_ zr3hbbSC4g3zhBbC|&R?e016iRlW-B zW8`-`V_f?siGEtoEBm>Sb)Y54DpRtPdAcSX2!2g+WPnjmkVZq-!C(`Z7Wy&u8N=}b z23OMd&5}(rq-^fR%{YW%tqJ1GtwJw}*?shijQyu?k{zY*KOlqs!+wjgTQwgqV zKOVbINO2PA6MNVXYTMWw6U?r~%*WjgUX5~Mv=oPgUeUIl_9Gih`8J65=PV!<^WE&$ z!|S0-u7gSPJ?(ofw`|%iU?g^`^+BIc>_4$po_*QyDRa_8f=f}Jz|Rz^d#?S11;oi- zi5@S$l#RyN(LO7zQ*q;e70+e&T!By3XYvi!Wzt8>o@+N9jk|2$b>a6wdGyPLOMY-k z--@MhzPT&*mHx4}6_sGkw(;$vM_BkO=K=F@ue|BiA z@55Cue9Y9XXP*<jxL$vc=A z(*C0f@T=l;mE^;L-;imF?+<`m+G|%aA;;P8p@cn2B0FAZJH-RAYi$XPxCR-yg!B@4 z!+G;2jyPU*uB7`u_Qt3$;3Gh${n*Fsd;5yXS@?q4I{O(@w2Q~>`|;}Pu0zpx(1}l> zpCxxtxK$bDnh8*Si1#|h}!wEtnQf6cj9`OVJtX|MTb-)h&h%Ldl||I({M zA7Q8WdtW%>MmnmtHhlDw@$g;dW^_7dFIZwc(Glv=e{v?@#D%8Cd{e?T%@MTbXTgGHBY7YC_V)gOuS3`1n9jBuQ~Tyb`qEXWGB}O!W$Wr@cA~x9flKNS;gYis{XK*5#q#6nlww>gaq7#C`(f(@$T_Dp2ePVY>(e8_Sms~`Tg&k$>!Rz z<8f%E_u=ZjnR)Z>cJBY4bM9FbA1py^kD=Ya7r%7(m^X?44woz{NfbWKo+iDu8!JY+ zs#7OnF&plnU*i378J#JY=@yoi~}DRN-E zj;*fty~pV@`yR5Z{9L6Au17zRfKE)ZjjqS$nDp` zbz}3ZtFs#WE$CFa(rn%%&KDJPL3_1gDcIQi#H1DfuUuGz)yIHG-wfaqHZ-ysXg_0o z><{wGv$|URhU~cjpEV{Ho4A+#Wt?^7m%lMsO`kj1)Mrm`-fzVvSC5t1v&CD0>xw5} zZKP%@o`AKhbmIxg2J&`(Nx0OtA?vq$M_l?8JT`KPv%rk@IU_?+@@gDH#&`nx9J@>G z23-FE#k~^^qhANBvgI1%JOrJIuS!5?(rrl>DLtxkmnjas;=?NjwBmKhzR2nmG;|W@$61G;5R*vx4yD7C z{>Ae3=zkPbA^C2R8Fdq7VB(V z7-0Ri_-yrg(4lZrvB(r7QEN_q0P>4bZglH|$#2prXuRy$@n2o_Twp^U+Vnf%(s^)+ z^BBdLxtUKIdr$j>KNf@BwvK&f@_3Z}uW)JFada)ewBFip+w)YdIoc^&c94-{@Cm() zyUx2h!0QgKQP#93mJYcX}9i)Y>w*2kDLa^|@Q9!fR| ziXo*l6zP-XD4lh{X%?p+x0}0#@pbKP}!}bc0<&+RE?jgIez^ zp*LMEJ#ucxeIG@2=y@AM{%`D|v?YjN&)}s)kaq|>jGhN`j7!2dH_pJ7GO+)<%mKPH za8vEGxh)xI#T-{muq5NqiB3OtV8tMQ&tUO{>vEFV>GDgieo5n%S(~ga@eGn9iuz6l(v}cap~?1AU7< z4h%q7Gsf%L74Mmfq=0eCcDnPggf~bQj|mg*G*& zvLms3B0ReO>w|{-&#~vl{4<41_rv_;4G;KD)p{_M^HH1gk~L#YQ zHSkJ-(@8UB|J?B~Ot{ok(Yfsf*1vd6;S#i>c|aD{*eQ;#Z}TrXeyE5ccdorY-q~@V z)|Hq5aq`EVEJnXX99HJpp6x@o%FUoyCE63a@I&GJVwk<**c9uZg-4Yi5S znUo*OcPdB&SMn^)r?~)_KVQdX=>Dr@|+QK9u*n9>2N7$*sa9_@sCta*VJ| z`=YSvlf&oVDz7en$y`Q0Z9oUpfX{I&`k^jpDh>_{gVWH9{HCNkP&{Gj3>5>gp3;a+ z>r){XpbyaO?f7W%}!v`^CrMG$ampQ&zTVR zIVus^^As;I(N)C6W8X>1hn@YfAAUr*?jUQ&ihgLK*h_|aK8W5}y5lfK_czKya)~cA zoxCqxw9tf#UNG(OskNJaWn!FrnBndx@2+pib0f*$nUudN^!LTg^Ap%vjf(mMVPesI-isPlbRGGj4|wPE;mi5$anNM{M$iv@yK7*rL_AeRu<4% zUTO(v?d)xe%QLKac*>uLUyG?#Im)@+VgAp3J^!ygG-|5f9W__++wH$PpE`1_U&^lU zPuP4;PQWyltuf)U<>X>qO<7}tWh?o-!UXp&H_iLjo58xXN!I4mv}N|)jrSN@dms^Q zTGV`Wr)eoGAVxp+?Oka)D4pDQP+ImD7~c`jHhNlp=)=C2qk1!aM>g(mT9mkQ-1y4Y z(%)64lQ_nqy~|8!593g}()ddYOxwYYru&0;DyaL>Y1WV4Y4EGi&r0yZp&%3Yn&D_I z=lk1DH90okFUT_$%br0e3r?cTl@GgO zzjM!t*UYv0|M2Rz3&x}$AHTiCIcYd;E|(VJZ?Gma=bHC>S6UeJ`m)0O@!L3tUa~ZM z(>3-bI=hF$p6Ohpq$vY#=^JDp;5%EeUsbGh#XRqW_l=p*J6p*`^pw>HD<8F$k>H!U z*@yctV&8KuNYna;C~^MFeA#&EnRh#^gc8Z>l^J4Rg+~ z+-S-jsMucO<9pDN4V_pA9M#jtUiO}G^*r!RqJsqEEZbdY7qKRziMKbH2>v9p$CNxO z|5x2#JFt{Ts(I(t2+uPJ%3Us7-*^fAdXI7ddFfAlmfU&MJj}@beXhLG2Q6RC*yQz4 z?e)Sq>nut!19DnF^(tpz>d*9-y1N;R>vd-8?}fH{D{{{(*?zF6q<%o%blTD|bwXZl z5uHPWeWGVSI<!LnSdt4vl zC7+>8(AP1)F*flx6IYH6g}43!J+jUgIP*e2QoieU?4eC`eA?+$Z)dt0!-Z9f}rDgL>Q z^CUZW=`j_Hu6o6M)9+(n8;tH^ZG3@#e2#K|Zu)b3J0|t{elsjysQ*#RqUUKGH>8Lt51_POk{`n;F@ak6yExL=>|?7ZLW>lbHe zTp!}SH{+E)tF8y!`kak~_a6wC{?&vzvs1i>2=<>ld2l1Di}DP_>ykoZ1+U$Sib7N{x-w~ zRNv861$gge@@iIZ{|hObF0W(Hnkkx}xZg9g&b&Ikas8;$fUqfpOVSZLv7uCWcrez2 z4!4zbl75yr+d{e%z7?n+iKTevr~fxxvUD^s2fntv_2AlcEwLzKZ!R$-jp%#Qtu(9m z4I2D)ZrE3+gqx3IU$?L4!duBoa;vozFEl;7{$Nsv3(UxALX2NNhS(BVXA&MRO>ta5 zs&wzQYijGm8!vCXJR0z5z@q_=20R+@XuzWZj|My%@MyrJ0gnbe8t`bqqXCZwJR0z5 mz@q_=20R+@XuzWZj|My%@MyrJ0gnbe8t`bqqk)eZ4g3#ucqXX; literal 0 HcmV?d00001 diff --git a/huagao/hanvon.bmp b/huagao/hanvon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ae1a4c43ee9c20e00035be33e6a031488521a80b GIT binary patch literal 76790 zcmeI5S9n!L|L^zz`rMtXbA7JP^Zc*=Kq#Rn1V}<}qNsEQQEVV8f{F-&h^W{_6uV-< z*MeAruZo495J(RY2qZv4NCKf{&S%zd@5yA=+ABL1eIM4d3A1KRU-MnRIx{IF&;R#- zMfBB^fB%nv|Cigz{QqB(|HEIo{`dciMD)MdrP_8iD#b7Ub@i%hxTtE+sme-q^r-s% zH}&qjYSl_Lf4;iuMwOAN1`kyI`l^1(`qwvE4IH2{)76cW)x0~@W6RWrH`EV5s^Vf* zeo|GRRp-yE%a>JSqg3fu9E%TV%~hrNb;cD^X}szZ%o3O^Ffv|6?T-(yF8ryfJ;7uq zeR!ZlO6!n9oOUKsW+dWdO7zx;Gp6(9tLoAvb^d~?t5Y>+RY8IJ_>(J39yvB?!ro!S z_76!Z8Zh8k-@d2%^gh?C=Y^h0my^0*?%Cr?^p|v*NFMd=duG6Z@|3~FX+sZWj{Ix> z-NmoGa_-k()Tv61+Vk}qzF-a<3(&)R*?Blibf7veT}V$u9<^A1d-Aqecn2nEPdnR_ zH>3;xV*N3az0EjlUb}z{gjH9oLwV}8*VU|<6+==A2MsJ6(EmjLzNh;3IoqdqorYJ> z1`r0edh}>?ej0E*O1kI)t}Z!QW3GSyia`U84IWf9a#Ychr48SHqfVSqwYBQfMGtDt zo6*I0@dmY1n{iDljn|{jZcK-l-{A$u8yP3QJveJrR~yykE1JMSz^ba%_Mg=wi_0=I z_6-_%v`_L`5YwZ(;+NDz|Be1UcnO}sTrXfJzod(TzoaD9y<1~bdM_go?A`l(-+q-t zhUDEeIp>v^YYXyKO^xO!p`cf(~GA!w*$eRVLS; zfByOEtFKD2P9qN=KFkE%xpSvesYyoLOgSb{S662WbTV>#sQsMPmP!HGIXw|!KDOeQ+B zYu~YBM|yg?N!+7H4->WnJ$v??GiT2C-+xc-H{X0SkNj1T=G?h+v}F7C?RH)}oRpMw z=FAzpwS<|x!-fsBli6YBuan-~PMI==l>U|wIe-5A76*!PC@CpfvSdkealx6}v zGQ*OVmbPNW3Q%R*Ac1}R_Qh)n@yCxJchXb!gb5Q&v8Hw@M*5izphK zR8D1FIGmDFlrre>;DN^n^s9h%jLLI%;oTI3uz&v(X+yJ@Eh|5e zt3|hl3!dCY`=Xz_F2z|vL4iH$PMDXUlapgcJuvY3=bt;dxHYeo!0FScCFB16`+N89 z?N1yM!|WJ1aA05p=AeA;p-+AK^f75n)e-~2_BZ>HM;f}}maaztJ6Lb6Rx7%pDbm>z6{{7<>wR!Vqe-~D- zULBa8NVp37TWIHP1J2+TFRGeq_4^;_1}mXqzz8UK1gweQ>(%oL^a*SYP1`?xdhY7g zRiAyX_U=&?Cp87Ct2<`L{}cYK(y@bKZo%^NVY#>Bk#+H0oPz_)SY z#0fJUOfEYBS&|Z-c;X2=-U&lH;iFcrT>0?B58rgtO^_m!z~3q!QE4p#uXoLuF(Y2$ zWy_YC_M5=hUw>`VI|04~HM~yW1+V3#bZ%+nx^?S(`JxfeJoAi`-rSnen>lmlH{X17 z?AWo2ii&O9wv8S=+N2@CfWS|}0m@sr|Ni^!VKIe}^1%lm^f$v$eLJO;Ps!!w<^C+h zB#twY#xARddUdKoJ-@CF6(TGgc+%>O77r)s`d5IzTW>wNVS~y&s7{~KvQ(WX zOKDZ%Wp(+IR%A3ZXd;C61g2d7>UA3ZtJUexRH@1eb>yhp_MKY2N==xk$svGCPCkuF zMPS{nyXw}X5iS&o@W#mpw|=M2o>dn-BS4I*1$Mh5BMoTyxSKcTe+hg^!)xVBjbLHV z2qz4@q=d&Gf82RwZu|A?ck0wByCQDic;k%$0|uBh{=iQ^{Up6WLgJ~v@kEXsInpjx z!t!khOiva+32d>CW&q!N?>&EYh?vx6(wKnh5yT0EnKvROoIH7wZ;weMf!VWXL%&Jz z!3Q5WkIZdqYASGansMR6g?QAIjPV5VgmEU)SZ$r!xl>J_UN&gZVHiS~HvySwE|~lM zldFcL=HGX3>Gthf_XuJD5b_gzrbgHmjWF;8J%ioHv{qcCcI{UG{#pI-y~b14Pnt|- z=cr@H)yb2p@{~p!nB!Mk}ypQO*u&Nf9!z|3WG1*$eCPo7Llf0;zWVmZw?aNq#(rc9|K@Gk{2o=*1r z?z=BAu|)EXLEdt*$n8^4J>}1cSSTQ!D&7ph2z3fR)Z97Z*dN}(s*@`YOS^r`uG z6^VMDXi(sI*M^WYEDh8)CfHf-45Q6qQGoSFOh6ZrV! zkDUf{8^Xx(VUYBuJuqxenf9&exQrNICe(>0FGZnFbkfVM3>Pe-zj=}!>PSj^R3-e@ zTW^sdBO}8u)(#^J`pXomZznTh6hnb}oJhpz51YzsKJ7&7f!Orws|qbf|Ku~E3KO&8 z6*U>_Uomd%{trITIDlLMNL}xMF*Qu%&0@ zefp^u^?Pk$3B0r)^$e>7&y z7?VJ9nJ!@5@VCvxp!_r$?EvgFOh({HN;23>Q-}$mhq4QC!Uqo?G$~CW9A_RSgX_aK z_WW}-&=1kON0siLMv*xV4|&hsXAXKwKiEP|!>($!4H^c*pyVr7R*W3Emt^3nN0L_C zBUd#ustNnoUAgM~XnZ5}YF&O>?(MhdfAC>r`3Y5hPQ&O#h5F(PHDyYfvDkI*ewFgk zj|?4_`{o99wz^9#+94lz-Uc7LyY9LRuH%+lZb2P~4jV~p)22-ru8bUj4DY-*`_`H1 za5a=Lc<^A8#>`n}D6ocIG_RTfl}bu8J>`~M*qJ0HM9V~)VkJPCmkm1}E4RMB9{4&1 znvAAclK=JBUnbrOApAj79q34!Aw!0kUhw^JGMfGhuMqERYDU$hmvU(KmMvQ#gxorh zBtak_4%JUdNs$D0E(t>;V`J0we-q!>oQQcTgpvWW)vK=zN+|{RaT}sNuZ1*_v$N`h7aEd6%?Z#Z6h((hL>Nu3jKq=cFl!Z zONQV6Yvv#Ucp-CZzao_Gs5y#@iv!hhCMC&?qRjLNmM=d)|BEla0ObG??J|;zX#gbl z_19m=>_Ga!!lgZAlt~I$?GJ`2 zfdD8Jo5t3yTP5CUA?$jHft$e*e%>zAgc){BgCPmvw@nvJK&Zam1q$Srh6PgA_&9^> zV|t#gf|At^8eG~l>AY5}H_iGBnpYfGgysUJhSqU-2-9TjysD^FZ)~_QVq^{ogOQ7J zm=?U87$HJ}Gy9Rj8Ij%pNA>8Yol3wuOeRgjT(CV$;|x)(`i$E7r48XJ`(mwb`QZh$g zeDOsv1jmK6#1t@PIt_qqh+qNQj2PrhXYyi)lNoJO4nN;z3OB{V=!(+MlxYGKi-!oE zLY){-m3QNfH=^I+8-v3O>FvDS!v4h@69}-O;-s`MDTKixFC2#b$h4nGP<|FIcJm9% zgPoo*rE!sw2>^|6o;;o&1fdN9i~0M;8wz$&Q!>kT1!=+VeDlpE@QP^mkbwXt>>>fO zWbaqAW*^rINgP9PXpEuL1`uJPTQ-t3j65VsO0C26XeTKpF@L*}K=Z4Y0TZ+h-R8=b z7f}v?^}1ShqFk+9aYi>-D@SmZysW8OYW_zbYp5An%^8E(Z2(1&J!-}Ox7~J|^9JnO zkng5RCa=rfIsyECq&29kfsS|@Ie(#H{;7cvR=Cs3p+koRJ*Xe;O6^I9fQ4TP6vE() zVr{X>&PbTPkeCK%#dM^0X(ZqlB8{?KIu&TFmogbxz=}rEe5*`d)M9&>nYRU{clu(o zm;kCs(m(gyb0)?Kpd|t2d-v`&#e#TZOfqUWVF~Qsz1t*~KodP{_5iX3kfNbWhW2iPDU4k&pD|#TqJ!IUNY!JX47xofx`27_%R>T3T=Y?K<&VdHx zJgpOvpQjlCNgAd}7x8#B7zLOAV|hO!w*lx`Gm3MwRUJ^P*LHx7Z|Y`Klqg4#)zZ`V zv&x2VfT%#5b+zfH18~OdgFTnQmI>udEBHovik6)(De^h?n~y&F2rD+`H&GLWV-fMr zG#Q@9Dc`(spjK2=WKv3idCH_VX$aVJ1o=sl!5qdbmiZ{62@sz*Zyss_n||9Ro5DdD z#rj1nlNfEi)XQH6@Y!ddwOb|0B!)srK=b@i^SgPW;J}qlnqj(Q0;YB$rMq_Rl9VQ% z0Ewv=hb{3yfUwbJm}J;;e>rwWWIod)322=8=2xR?IIqyAj~;zUTcVS+Ws; zaqF#zOAjk(qnWmVth!3Qvq=pdlCQ~F%(7+h;RFB~MQI(%fMZBe=6)#acf>3?GMr~)`xh!)W2?^j=|;luJl7*Nx)T5{Fc zv4!Y?P|ctM^}6f~M8Iu;CN?0I8+E`l5!s{eguxSO3_Y;(6Uk%`r-&#WjD-v~Rm@jX zh5zNl4n6kRV}OHch{y4yNt2wECJPe^?+Iy4b#=9WB9oCc*b~s&z}=aQ#GA07L8>r+ zQApBG+ZWM1lE9~^hOGHMDmIsPg7eJ)g;pvCAZdEm&qa%OukRLw0 z0EBt6+78CbFG~Vf+i=D-;SHOqXTLFtv^^aH(S~|Wayf;VcZ>UmX+AQ% zQA5~uwKjbB-FMrKnL2f9U`il)%?BVjyr7a394XH`U^q$gAagjMAo#6GF`AE2}9tGC#rc( z8fRvmvW|r^;k&s01hJx~j!!3RtKyfE5Jykg*8QQotv`h${BrO+{ zo5M-!y2QfJ_ssC&dBBTeG1~F>^Dk8DkRq`~XbyAWQ52^@@UoABoAGFWfN8jB(IRK; zxiv44*Bf37CBT*WOE58xUpUA{-+`LZuEiuyB!Gp%_#z70UV7=Jcp1ej1hpg`F`Wub z4C(#(=btI?&O7f6Ou$ry9^0cKwG)H%X%+)GwQy@ZeEB9p;rwn@fz?SQmGU9Pd?9)t zshxV?efQmX&=Hdu^ge{pO5yMUUw!qJ>5=Jwo!G!MVZI8B)YVPVQ3+ zgZKGodhSERw2{nPd{$ehzWG|=)6p!wrLgbSL#qd&VHp_(>({HoB5x&&@Nbk8deKa3 z!Ad}@P|yGTGus}VMa==)GW8SxwBSx*k72nTszZ|mrjQvlI0#$6{`xEFOMe z1e1(E#%rAR8zhMCr$jMqmEaQ>UXI7T#N7 zszQWvvQ_4YJU~Wz;TT~WF*l3FnaKWq&Zed2FMp!4q*&7!vd~E_Bw4T4yk`?I-HHMl z|7BK_)@zITw_DZZn+^>eTn5ydz63Enq~>fV<*}w48c7xmdyg$WiFtu807SUQo2KNH zma3S3tEry0afwa&VRRS)p#9 zlgH#0MTrKbr<>O}>v07|C1h;U_|mQ4XkHX+oF;_rxX8`2m)d%D_^?{Oyg_?hc{-P< zKGU-aK(wgzuK6cftVIjqLd%Y-DK{O~Uk)tY$!A%z_Wt`Ch0fJcIHOq9$*k?QkwMr- z-U~0h;MDHiGHspg&MkfxAy9BiyXLq4rut*9c_TZu0pJX};*l0)nvxPVaY8maM!}6x z3p~Kl{=pm~O9{tFde(TsK(2pL4IEf%(-lY{KQaO`B)s`|9WO4_@YOVonH;5Iu_}YQ z7VixR4m8y8nPel9vkK)Y(jNYn`l}FAyLfc#JiO&w8!y8*3KjhAHXMg~v?&X(U+yFSp!vhP;@R&E=OK^S6-$Msg`tSlrPSPOrjL3j&$>MXz%G8DW zsEy5Ocw-an5^AyF%!8^%tG4i+Q~2eNAFmghHt9t@z=01k(Qc5VM(qP+ zix-z-&Nh7st-I|wLnR1zXVWkP5hBr&`BhR*OAuU47JmR~phe!#DX_&`=LNNxz6}Yw zpo;KTwYCAIcd|IQ;nkU^9^VMaa7{dVM2#9<+`A83d&KNjo-RK%wRq=WnuK_kC!Ld- zi?wX&lH&+%!eI(I5jCUME2b1LeYA$02*gs=m!fb;MXb+k+&Md4CUB#%fyG8z-bUu@2X zjG46jubqlr=bCgekTlQP1jE~(e>7p8F4(;YDYio%#dE6zJ)i{JPk1fp#2nkGft>^} z#fFz~{psIl1R@c>zszn7xVPMr162^|O6U{%c-CJ2_=8sTHBp^L4U0z}(JLx5(^+{| zA2qXit3CTASK`bIyLi4q(?1X+TKS4o>et^C;{W_RafdsMi9m0*lTt)r%;+O`-C2Xm zpH$jFu{rkM7cr9rg4->Dn z>+zj80vcwW0&uu$6D(^NF&aDW>(UWB8AJ>w$fC7k%{)dwG*9y4YeuKWuY zDp*Zc$86ff9{E*FbJn6kU6}YVjhN!ze@~4W=h3YpdBcY9x#iYfYt~e<8TilJS@oxO z?b7>Nu@Ba|=T6OHzlD+sb<8W0)cW(bogxIt<}9Go@tq&8v4 ze8mXx4S4MF%QT5X{v)sJ$oogU)<^{C952_JLv#n)W!Tf#;UbUVg$Cr%K|O`FSR**Q zq%Fk{J-D59c?S=%SI7~TapK+t&R_yr*NlTAx(^ijrKRe=`;XutjN%`U;Mub({`FOK zQ#q&|C`99@;fVFw^Zczmt&pYGtk#kilyzA8?zwm7=CDRv*hs1eV9~276pPVMan-^r za%kG2sE?&5rD0CX$Sh=6ALuKP{aanvA@a9+9i7^kNQ7DcqE4J|!#p)k!%icyk01oaB!h=@u&5iZr$L@lY96e^=)@`1rS9AZ7z#*Y+ z7}cIwruSrx>K^s-wJWsYt8X-Eq@wHB^%1xxBM^zOU~BE#(ZkM^ zw?DfukUMr%<>%@3%g?OYckewrN=meo{lgFMSopy2oS}qflBbg=7if?TIz08(WBao; zdW7?Ix@eayk3{~1kHz$L_xy5vH!?^536n`PbP1sZNn78;%9g8;%r3aD-DzYjCT~fRTJ_Wp@Wie-Pd<48 zRXqxnNs|tj6l(WE=6@Ax8(nv%!M0^;A}t=MULjuF~Wx;c)~~Kn<$4aKTBa+RLw;)Jw-= zy9~R?9NRqEDvL6Wp8BTI7l&!#;? z4YrW>9aJ>EbMwne<3Smn8qd_eQyC7ID7v2vrNn=pC+U$u$!Ki zkDZc6j?~);FuOToRdZ-DK*TbI6cI}j=YQcgwP4r0OwUuKd6bt1sNpL%d|0tKIBQ#A zpPIRMoJG9rz>5tv*o#Ki#5*L-+_H9`EnMP#5<0Lk*Ngg_k3b|ce3*)EA{8^9VRHg! zFT7B5&RbNXdk_Q?nLa{4{`ynX53SitJFsVWpg&4CUYQwnpol>YoUMB{ z$~Oj0@TRV6d8l4}{Gs;YMa4IE^nTW{;d<51ORyz{*x>|=1yZ+8#nDmkhRhHD=-IQ+ zbS%!~WTbGA3Dj7K#?Cw;!x-`?!TyFPOQd`|4g2S?PL&S{yFRkPH5*E?b3XxYIUSwt z7CAJctgH<2RO+?!hPR~ip0=kAA$i;O$luLKL<=#oZBUKM5i#q@Co9l{82w(n5k=7s zd%6CFYJ@XzcEiN|+9J%#v-Vv!w(M|%r2?s0GuiC(yvCWwH{Nk)2lI_=J8Jkt0wD~f zEUae1nK=|D!CrK6GH}C=J+jk0-;aL9sofgnsITS4;J)n^{NU@&ys7gsQRKgJmiZsqO6TFcgsk;sr#ZDA6e8NN|#4u@v%2QgZs5r#A5v$|UK>TBna z&sa*s5@`-GX2ipK*{r<4*UL!$EcC+z7i>_PCiaf*r>($tg@6(ZY!;Y^vL4X^%sn#ev1l4jN{+&BQwalg0$> z1c65o+FdhYW-%WdJFkQjArk&v{up*-W=DV8153;ya1a$JAE$?N76BJ0!?BAh8-}xS zEVv}uC!c)6@Zw#-*tUv0@mKASk%Md^k+Eaga=_g~8^jDrDf;5`mVE+o`arwLuJ(G* z08bKH@`zqi-5i`|h@C*25vNIFGs+q*xRLhoZTQk_4{R`B4rue}QG3{0wf$O9r}ZJX zyiX2jV*hRbz?&H68pn*cxCb~hB5*H9j)-8t)m907kQ_v@K$MtP*@0F~{1!KVHNz#$ zYU0hXoAi$h!{{QYMIs!hCFd6z;fw$p1XPZz6Od`3AM8n&pRZlyvBQxuGqaQ}fQgK$ zea-kf0gV+WD)=@aVF1p&uYV)-6+ZTvwP)dDrAO#=7A`!(MtF|yG`Ow~jYZ1<@!*t* zz&Rz6ya$Bpz#ZR3{zFEIH@PSQkp(~}Lfbe`3Gu=%DiB7LX~)}PJFmY-FmH(r9-Rs~ zqbaZoyDmFyC-#T!l<|5Io=cu4p4VTR#6VUfkp~xP?IIAd^&sfNvF%Qqrfs{Bjj+p; zhtNCRIQbZ6s-zwbg9jbkut9Ih!IW>hnh@0#YI+(cBovGDZex&bIWLMEHVT<~>p{J% zvZvX>(eeHFFX60@sV`Av$7xTSqY)aIhCs@^G!u|l!5Ma6fBm(sp@QLYxVw0-k$6s% z&C1F$e5TV*YWMqLhLq;C&7abq!V=~$ICkodcPocLv{;M3-nPZWt4QMGJx#nWdo=vH zy8Tc0HBUbii9EkfvwX0Q24~u#SawJqQdCfoz$#7r8*A0mPwSP-&@;Rx$BjF{N*TQ} zQ_~%1xS0+5a$^0rU<=Sxo#lv`8b}d~KiO>DE-j!CZNGuqi`L z%^{-k>h;IBs$P^JoOhe};5nv8r*`R1A`Ngdw&ymmI*ByHYnN}Q4@}UMxLc2DQ>RBF zTRzu2%9&M>hI`~}cJRls7AQ5M99IBnqJs;hSn@n{cs493{_z9)VScNvs`4<(CLoEw z0xKnzvN_K)&+LXiVafaT*CJvxaN}K2R?nmPiO2P+f_m!$_Pa_xbI;w{u|-qFki7BA z?1XrTR>IAYv?_~D1q<#Jjur%@R*Rcpp0n%0!xhP?5zB>1v0=0qad*|^;9>esj0Aj|}? zqRqdvn1yB0-RR@v36$ zuQ>Aj`b%uA^~AF6$B!xeEkoAYPz&uWE@F9jp=fsWKCh|yUw+xLHm6n7q-}{E>dRSy z@!p<^Pw+J+n9LO0&H(eB??hHs76+R-ol1OU0uP=7MsU~uL)1;NREH{u^XfT}43f_Y zobgT=1XW!;EFq(c8q3=sWY(;MK+3?&1p4-=89p?ZeNW@s!(zzO$Y{{V-wqw>oovC8 z(Ckr~Quxk0+NC!EoroDq4K<3w;r^*rH5nuJeej{)KA$xJTfV5v&ucF8HD%Hvu#TAc z>^f~>5KsL9{ZCDwo?F3IcP&}lo0rrTcThFX!<3g3_^EB%G?Ahtulx-xoO{khM(bAO&_(;QI22&Rj8)vqcl$5kow)>o6#M+LbgM~<@v`z}ddn0BfNf4L@ z?%mt(>e*+{810;ZOblsS>o}l%<%-6*d{+!-kSfRtx{tNbDt6$J^D{L$Nhx~$wJTMp zHAMjj>@O@7%N;In`yKQqAPj39Th}dGbSgC^FFn0_$dJluGtNKx?QUt!A@cGh)EHWd^ zyfEbl7KKp)TlRO~eMdVxX{a~>5Pd9%A-2DKyahN47rU_OloO!W{*IfNz!9JX?4Xp1 zLJC!_9Pf#PnmO|mizaW-s83C4cGYsoaU_DZiH+L;hnT8mRdv*0tG^(92nP%Dwb0UG($(I5s)r6enDvvY^UMoJjxc7H z^3$V#8nXPZ^@aW(3oq^=aPg23d>PK2i@P9|zH_0c$IS>gzj$Ba@QD`qlpOMoRC|Qw0Io=c=>~=tJy3_Yeea%^q9E(h zC?pN2p{LKx%*o9S*_W+RR-u6&a0ZMxnG3;4bRv3XO3wxyx!8pS9E=!I!o~*co>gyb zP;YHgufMMF@SQokdPrI!hAya)$8%~wFwqu{9-Y5qhh{s&IL12l(~q1*uaC(F*-1Sv zvGES;=b)f8CNE!o{dJD!T7j20P;{BwDDqkyx|R}{H*6;ijIX(i ze5^OfXO0`38LB2y+LA}=v_`|@+!zTatjt-jUHW7vn9l_Z{&?lpGPX@+qpad$b>Dqe z?4*U;Q}14yIBCArLyw2K3ZO7x&{1?2s9^MNTV}1PHr;783ij?BCzt&GyT&eDpH*FK zEIf7*v25QyHF{Km>~aFrNP#nE9Ajs4^pnLU>Ylr|;B=)?#c_%r!Z-x}kKYT~Vn~y; zwq9mB;1>mNfG7@A$8oj~Jn#Skyd3#%GJpNNhsoI1nw#ZAE}=#rID zFjH*T2T+cnxQRCu&p-csXE%wFL~R5eMb{&Bc{pPy#?n&7X7*shz{>>mdgPuL(o&1E zV8fc|3RARcmcq8(eDfZ*Nkor+|NYhYU9qp6J}>5jt0PD6??3QZ&))U0pdQp%c&Qct z9AMqMC;O6|hi)bHj4c@O?BgH?&tLe=!=>8!SA*MwwSk(R5fCT#*{WB2_o*8umw+vb z1CFd>Gi4q=bEt&uhj_%f5a*rI*++&Ok@K&NwVQod;vJTRNjDUGR_P0xJMDWWBQu`^&&Z2qV8zPfQKPnh`ISDB22|lkOyu$> za@IbRt9@0Vk?p`4Y#Zu0^Y)y8|0P3p_|C@q(2@T$r<~doxoz=)?2c?=r9t8V!tmjC}F26jSY3tWTeIQxtkfL6QXx?&?C_Q7V(QXPUO}NL!57mJl2n;?< zRu>zY^_(ZTU_l8I7;GVu*@W?>KWtO16h%Vf$G-dTzJCcmB_neuv?^tADUd=fNlI`D zwm7olhDm!^mkpx`DS}Y36)O$1FR2lHP#t9gAkJKhDj3miCZ8TXdjI!7=U=e!p)EUYYTTj6cXB~9{hCOjB3ciy}+ zkOUYod>z4-hMI>n0&tILNx%n32cGrLUa@$&M&>@IFAk1*Xi+t3lKY&2kz>v0s+Bb* z#TpY@sd!eOMvcIfm8IT&S3UoNTD@BTUV2%5x>=!7JXN7nf_O@E$(W}h1m8S`jIoW~ zy60Uq<52XI}C zGZ|RH8R14vLOA6)H8mH$E=tU7?h(nUdn2@pGj6wjrzbmTXd(vSz+=p?SH19D4Raha zgKr^3i+vqmd_loRqB2Iyj=aSWK9dr(b{`cbKO#8MD95VobjWs2s-`U67YaCvA}P)FRryT&7*{$|)QQ>RYtBtEvy z-Eux5Z7v7X7rir`H8_)j!eOh;CAT@F!I_-Ta!TEE?-6Zf_U&XK$iu7!2^lf6kRxva z2L#5(1jxh1ikS|58a0AbW6BZNfF_*bm@(O_S6BVMLtB$Ug8&O&4*CSP_)(PnB&;Jj zjHW^34_Htp2DbM;ygGgQAwWzUKo~+ER1@XP^5qS9KWfOHV|#GLIlh1lpx<_zj)ziC zn5d7PXIt_wwrHA)rgiDk>^09Est;aK5H_0l%wo7Q?=U=I-Z05{$$kmEoihvG&u``q zZ<75K%WPOzyXqN(z^99q3~W4riJbEaAUTW`DqJj!@aM!}FT{I^r9)X+Svz*@ATd`? zPL2f71hEkwwq{b|cg#K`rkl=3h}&h$mUUInn(B$+3|*Yo6ySFMr<~KLcRmcJYDpKF z-Q&j>qJsb~TC|UnAN?Ot10s;9L%Hg{dyb^09)hX?2-s0AiVZFuKjG-|WmiAhtoH5K zM|U#o&s1v|MG2eGIgczs|Jb4qo&CG-U?QkX8&(M2LY;`8h*tdfK8GwgWy+!Nf7IE5 zEbz_FQDPzoh&RTd1UgU@<)f&hMtlOCZD{%T?|B;a+ z{+c=S(Bj3%*F01G+Uw^xy>pr0+nX-E`da;p6_xkgTgur`=tpq<*HUAz3q5*XB)bRM zW0{$SNO(t%YH9~uXa+}s3dm?4W`y*Ns@L9t4L+rziBofGIlfv#4LuXz5aS`DJ)%6Qab`P?7!VRz zz8KWJ(f1&$-LPu49+KtE)2AI6lA7DEZv{X>qJqNV?MoHl57+@~t$wtAobN3-?lGw@Olx(++73(2GW#i0C#%w@C z@zqy)zYiuUZcGMkP5|Z&*(-f`0sdmB(jj0j+C0TM`U}|0)0OJyEcMu9S4NL6g_vnb z_0u900vyCfy9|5yqelJ1oYwoC0U{`YA|i*)oK^YOTUtF2!k}TucHj&(2ab`$h8+Tw z+Egvnw?|`A(p9kqLPRq%&Of&fhnGsqK^wC96Lp?F&^+R6{tFo-^9VZO47@$k@xpw# z`A||wYiD#wdKPIp)j``fZ{AFnz+6Z?c6#Xrv*wxzD+~pC_x3E>wENPkuz7tZkVy8x z#17_QBW!lmc?&+AL6(3E(_-1OI%Z|ho-t1>i+hZD^K(SRC7=dwmM_0_6c(<@TO>9$ zWBPb#8)`=Ifz-9*H{2TQ7v5hyar~b2;d`_>EwvCrMRoEUoN^dt2aM&2%$>7mA6mZr z2q2WKKMKLbiaruxZJj_4W{rm2k?i*1&xlT5AaP!p5jkWP0W#2`H8b?ibU6B&ZYA|ProLfJ1oEPe(k9UiO zhm}Muw2{^2@!n|@&OGTXHlCmX-Q&R=?Vk((*2Is2vzX=DaA*QGW-(-G@k8}2wgef_ z8x1w*@+u)7(4d0=%`kp|20{p-(m&7Rp8%2Cq83y9i!UO7iNx0<>nAm5P9<~{UQz37 z*hIfO=DntU%XQnlb{f(P!5fje|L1?}T6DvrOrz62ZkvsR|1nNZ^XAQCUO*l=NQM2b zF^LLW=p>Fe0`8lV%-8EXKaE>@i4_l;vUA0DqE$J9rz?s|1&b;UI&FWqIOX{CHc!WD33uzIP0{3C3KxlACmVf9Yw0|~J>Wmwl zM^;vr?dNNEGePK>EQzFV!kNhy3wRr#B2j(unYO4Q+-Rs-sFJYFPYPi}VgqdmSPSm2 z#sBGexkui7S`sW6ej|q6WRVmhY;c&UK;Pb^rcFNq4MPv9O=!X^`r1RQ0Gy3EKsG3) zXw}mf*w{xS-d}61$DQ=Q-KkbpfgKr4m^mV($R zExT3Y$B#GIvOi8}W$k2L6As0haF5Uc*e!JD9#z8^BTCgArGqo&#l{BVL4*>;JS*6y zPd~M6S>s!8s&BqgfBvEJ@)Rr8@IK~utV|UYDE8LE%m1BCXgeEkx#a}51$?%!0040m z8Cpz)OAMl6%_3ux88jFh_k)X0vF%8(yx3`jZ03jw1XdOPlq|CJ#({;oWlxI0V#6bU z{P9OK0VROFf-EgICcM}-JZ-VY7896Cos`H=Hn!~kcGNmgr$*C~z(9*QBbR9U&#BKo z)q4YASw;@i`n?wCd-DXEy7bXXzkvge03f{i(}(R%AHF*?;9LgcDT7OwEU7+Ou4Tk)as|E$f22Rgv=#{*@Zs~ zVVEu{DKY8ofK#lw#Z^cOF?dC%V`uF8uxVQxs+PQ_1Oo8JY|U&BlpV(Vu{{T;`CEvt z3e^b~O?)i3Y}tZp3|CBUZMoUSS&$aMvw=a?a6x3NjtS%Qpie-}#aT@6;Km!Yd26Ln zUO<^No$FJBBnP2_;OW1f$8pqVjj0;(iygDNH&HJKYJs(M^G-|TFXgAD<~_5fP9K%% zTgT=fs=sp#KDMvD_8PnN!~-0jlPv3Ia+zK@Q_sXpz}`MXCLl*;pq6%$b@naNCwf%W zr?@vUH&N1~^fMP)P z(Gc;`Voe1brm*t_hEEI&>`jDW60aF90`I-|9?mr|8LZl6i)1Vb@lF}x8)ol?o&e6G zUkcFX?Gu1VFlWv&NChZC2y0^Gz?p$m=LA}Snx}Zg4H8x4(4l$nZc^+UiLMfQY(91& z@2ATiF;nC?u6WXTyw>82i0+w}kA#n@$xtJiN5o)B!m5N;+h2l-!DJQqtw;aXWg|dE zNQ92)=|@An7%~DB#IISiX0ay(-~b{_e?|rkeIjm?@k(wn-WhY!+c9>SM=UllLmD4v zQGK9I;5-HrZ3RoXUViEP@Zszya!QM9j?CoTdYBVRBS35cE?#>3bb46CFfP$x8e?>l z_JE#zV-9vQG%0|r>$Qt!XwB3n22WKcGPYMaDn;HW^JUJQIeb-3mc#>mwXvn~;ST(s z!cQ^>`6A;ji!wznlqPIf=p4yrgc!cyiPzr#lkiX6>c2b5vHHl4sO-$zn z;33UG#mCtdZ&NE#g_z_L(3+96>d)U5+e!@_SlX{&Rg=W#5fwjSvvJ1LaNOvpamw){ zmBe6O+&$3xv$FzPN{nqZ^6zj#v|v%>*oMGY3LTQ8RsF5Ck?MacF;GVoXgE+9uF{!t z&TU{Dhy<7Ms_2aPK&q2qQ{#1^1LG5cV|Z&>ePf?L;NmQyF@;Dli&4Ns*fze^FluBr ze!+f;&B2xfF9S6b@S{^=oN^p;$hkJ!LN@3yUija9tIp#1<+If#)T_283PA(@1xC9Z z^6Eld6BBO~3px-cU@7gj-r;k>o|s*{I}K;n+J}_N;P9zH;(^Aam%-zPi|+?EWf)z~ ziDn;R7NrnuVt1iy!ify&)TvW>9rn9x6V9Xnu_L1#Ih3m&fBZsPT0Z&_gf>Wv zc=_A-Fkk{D4p8F3%iz+KLm{Rdpka@5+jYRuSD7&$ijMrV(TT}y9%bx9D;f=Qh?+Xad&%1lH$q zV~g=o&&&6mx&nQct>$%Qkjdis5Zb6RluQDs0}?sus6FlXPhLI)ARD!$f3M{BRMeil z{zkT^G?TZJiZ$gY9*E&A@f^V^p=~U9xun?HhGk*+U%(12d;H|sF?;a&1#nUK$RJgu zL+zrs28ABTSW=B!Bi8MaqxL+yw0zrEEgGUxL=>Y^zyG~Ez%ddW-1rWSg*mZ-<%E$f z5J5Nw6E3BT7o@mj(xJWXq{9A*Z4MlYj=~v*dvjUypWYsDcr8NS%8se6-|3^PXUwR? zZ7W4D=G13?f;{|6FbhPD)EKPgCuZxur`X{Dx`ldW@ZckYE|OEdDN=N7OQJ9L9423TVm4&6G)_- zc!^^;YmIysTA!dTM&4j1@fSu{f`=sMYO-|m<4>-zyT_sj56_x?X#9jd=^20FaW!n% z-eJS`^EV@XFEJA)?wxx_!4u0W-q=w8QO;%DLD_2L#6t*rLOqh#! z5VL#MzWq9eGw#^EheP0jm);s*Hu?Gcp{l8Ou@DLcPQ!&c^g?Y=X2);iz!pRTU1I(7O? z*SV)oRafu2&l6)-$cVNAn}GF3WirQe9F1XHw>{*2Z}|jm^wn zHIwP!tzb`H16~7O18FqSF)G_Icl~Tb{`=#D!p*Hges*h6SUSEb-;oy7T{b?*&*gXr zIIgv>?K9Y=(P^adWxWQx21bqsWP4g0+s?pVJR91ND(p@rI|bk60K1mEqB+QIhfOMO zs4{ZY?C;cTz-yp~2By?u7xrUJbsxv7e4a|SC+<4!eT=X4ayH1F)SSt!)I&6%;Wgkj zFw8YDyOD9%QP_f4LVHjH-zU!gxbq8d;Uirh1Z`^$bH)4H^BV9PU>r2QF@G?&XGR+P zqq4+^KH@kBdoj5+XuE;*CHPV2WE=CRDK?#L%AXJK|DxQV$bTMR=bbcdg!U=Oze}Bq zTQc)L;s04)16~8ePXpPy{O868xhIm?29;@T$}bFUN{~Ok7|U6dO{bM<_2cRbn}>63 zLH>H|(!3;X%O278eC*qigD9rGH}`&O3{D}xA%Skzjj3<=el~{3dgT8I{0=+-rh-?& z9PkQw0Xzxr1~-Ar!Rg>|@FlQ0uy-upo^#V?^td6{;z(oXBS5sy25}Wi`8!y3q$}}| zOx4ipR5}z~1?~gSgBf5ZkRBcclfVgJ8&D78Xm>6|@5P+29ao9`Rl!k?x@(oG<1b~V z)#Iz2iyyPZJtpd!2g6P%j{I;oX!}MclWXc*<#mi{3Fd8$Exd>}W>vCDx-MD9)zAG@ z-^x)Hw_~Z*5rdD(-!TE#l_|3u|2}+wTv@K}E%fo(X7JN< z?Rx%{_p^lUJyV833Yz3O)cX-hWpC2dV$P z4_tK~bCfq(6G$wLsV83dgGNw}cH`ng;A-2>)4j{?JPqE8l$Y%10lTd=IhX!y9wvP+ z`7V-QDLtEV_VF*S3L`zQC20R5W1)Q6K3EA*-6XajxxI6*h zuJuMi{yk)Qob`=ov4&{NOlIN=UF}V8A>MR6*XPFZq`i-|Ub63fv@R(sq$KZLU_WrVP7+8*$nY< zk?f5rXCIf4Ki*Y=ypv<b4ieA~`-Rv4*?=7#pY>DTYX^=sv8oQ7RE8#gmncg^*= zO(=H-KFb^Bc%``}8^&7fsT_~(K3^|empcg`X<-~c>O9t*X;a@D2%1Er<~fZXa3 zt?yBWhj{(~i1a^^pA&6I=ju<}0~f7CrtE^N-ZfT*i7{nV@0(URI~i9;@_fxMXr<+w zxMZ>ORR0pIj-8auc3D^Y&yGf4m5*(CwIwKQ6{j%SAL2N-XpXELpI%=J3U4FpB~6(Hs~K6scSxEF*U{*w_gHT^c(By8-~a277wLOzI{|5QQSI?{>BBnyh+a?-}s^1 zk`^Cx%|1>d-$mPzX_vFpS2`+eN?u$Wc3q`a?nDQVndC*w+UFYQx@?eP^|+(H+WJGO zfP6}upPiPyanasn+U4x@&s-HoTHg4E_I)bFqcsPX&Ab-lM=xlm{(n}oV=nv9yS&_D zd?DsiIy&b!6n{dFIWE5Pr@H%6{qmn)omMn%v7b9TtvIfpZ;dnb49mCq3@~E_k|8Pf zVAr$L3%O>>uS2>$rmW&Y=L5+UrE|%!d78BP-zKHP((|I2ayjyiy($$C59R8-ObI)- zr3&W&({_@hVl}e$Hc6Jax*ErR(Jt&rKNVBo)NSUvbm?m2B?mucWx@NvRY&cOXlf4H zwqY#xuB+cFk3OyWr%RdI9OF_HbMxDB{nfbowazceH)U-7ye*7;8iUDhI@=BkPYgi3 zXezR~p1-&}^?m)OPXsFi(aE4(`K`lJ#XlQ!coK+@tIh}H-w&|inH@kY*a^7GD(@Iz z=uaeE<U>1`B;)fKwnICcci|_{R}0Sm8rq=3a^|j1kGacHtwH-SmHenU-hH00 zwTz9q!@FedSV41g*r{%@@si!TjmOmW+uc>YZ&Me;F0Nlx%3n;~lYs0@oLv!*Gk{IH zzkR`-pj^KaPxS-&5OMq!OEILeU7XCaYc7%q^lRbeaAaWeddYa4+#fQ#3gB~ zisO+aA0A6Xe=Nwq&GCcY@C@s+&WI%@W{i@_HWiKz+py$RIc(O%e*6c2nYPSxT+LB^ z^HHGR{kZ!2t&Jm%3BCk$&)DE_P2)n2<;IJ4J1T4Jw#I02wqi2ZT(m2hHa|OklT`t~ zJGR_@rE-b`%Wm2{OnM&q@(J5f5wVP|;1L-X(rxqZjg=Ql0Bi!lXX zxT7JHdAV7!XRRGzUG(>`ga1uC>E9)3%1yGzk+gSMG=9zb(w2t2`euL7SQ;s3L*kyz zH2LB$dt;OCPjK_C zKgIz=*N||@VCSh_)mv7f>};-!b_1$o^DycARKOzHLfI2@J$ihMYl`z62cqrErtJW1 z`Yb0?K$K7PT=LoL6Xf?q%S6wO9`rwsUbD}ia z^{jrO0w?{(p9$jns`yD-X>@-xyhdU)EZm`&w7q zVNC4rb{+B1n(wYMHA{US&aUU%-M7@{ovaxB#V7%|K zftyd?<}%hhWPDTMtyo#`)$|U2Q`3UgP0Pr(A?3T(VO`O+=6Vf}W8gg>xSn(6O-|VM z6=is646&fD6GxK)!+cf1Di3*Yy{`86X;SA}gea_`ATuOwxLObe|%%yB)X& zs7<>sD*X!B2Z&^gY+g!BSN{a^Im*$_T$C-c>#OdAU_7v?m6OAPd?AfhrLQ29@K`ej~K$v+)$>^7Fsj2^?&L?;XA2i z#$Sdf{I4g}81!IJ!wl_RO}ox@i(PW%?yyB@Y0Q7i#I32jJR7thXkV{k`WAS{J@<+; zk4wR;kzP_BF(<>ViH1<3X& zCS~ju$*?WM$3B+hsd|R&Iwozd#T`{{H6Wi!a_RmxhT9!TKJ|qp?WfU013abouL9|P zGaxxe3~6qPKIh!SmHdy3dTBXuNdEuGr!69iKN1fdSV5 zvEARr_tV^5+)3H$9>ka>wq7Sc_EQ`v8)O8QEyCW+=#(kqzhQHpK}P*{4J55cP~Yx?#Q`4iN4zK4%} zyO(JT`Q1H8^KS4yfc-fx!#>fb~>*vyp|Lc1h?BPis0uD{_sW{vH;Qsxe=kB)8E@>eLklz7c#*(`qM?YKc|JtFh| z@N=$>!uCDaeGjA5?E9j^#xPO*)n!LCH`EzZFVmR(opV9l+DO+tcNup6lGi}(HGnO6 zA=VxQ1;tJs)G-D-(njBXR&ia`r+W#Ymu^zg{$B-jq}iMs2*isQ0&I$n>LNVHOY0qA^*n0&T0A8puFaP zcK`>2??j;3X;RV}OvO8+Jhn~Bz?btH=noCB=lo{sf3AM1ytuV9jF+_k>f+{xwv9^P zXJuTIJ6ZeJmw4TS{G~VqYo3F)!l zrM}kN+^sk-HsVsSOyBV+)>9tetv9wV$gwYU;e_hOSM$f|-CF#xw?li>lzXlzGdIaN zrN=Eu2G@OK-`-^Vhzho`2RonPHQ+VS3k}GAxcXz*&x72fajaW{+&6ViF&kn-1+(`d zeg^Sn?fG0JY>@UpEBaf!uf;p6Tbpau9<|mGp5eM@?8ftP@0pb6pKC(a9`B<`R_(Q4 zzOKLOHQ+VScN*aP&*k353JO1uZ>zW#2*2nS?1I)^K^lMMXKPK7&NSC$Y>>uO8eb{D zZwNcW`?e+if3^4WNXnn}m*=}|Fmg{!%EOoQ8t@wEod&}15gK2GxJ$H87RO!X+L)Q; zUD2~miLsg4t6~?zH7@k!b&QQ8kG=ErJDPHRcbwh;?+0azKApTgcxqBOv`t)^~kMtuj`$z;#_-Eo_G8fRyD7c^q--3FR*(LRI|suSp#M30oj-E%AxE;ttf!8 z)+^d;gp_Ur#Qr^b4U8NO;HUiF?tgZ=IB!&)F1qdG6Yj%W9iRTF#kWZIw(r}dS!=m& z4ck8t-u4=2J1u*36Zk|8+xM)!1_q4=utSfTe%Ip|}pY287e%b~p{-T}7liKbr-HFa0ocE zgzs_Gnh)h~1+?aS6!0`cHDLQKJ^Z1je7+jBFi&=v;e{=WU4K*!?^@MC4~vY<=Ga_2 zJG2Y;A%7>%_C)hl_I6Oy7#sZig6d$R@vLmkd{F5=bzSewy$F5+e4HL7lt}wq$VRUZ zWY6{9p>s_!`9qk(@sso2^RO@Sy{~F+jz0Y})0eSBf2@W_f7g-UW@I+U8jj0!ds<`g zK8V_!xO4Sa-oXvO>A+#o(H=;2Ctxjl*?mjm?oau;N4?*>7O0j+Q*mvu4ba|Y`^R9P zQvQA%cLN)MF<>A__U6;zP;d$0y@bpRp#G=*AeRH_M&SL1@cU4DUr_ft45+*v!iJ!O z1*w0Zcu(Y4rZ2P3@J~ZQQP`m#_PEAzYNhpI1^%Yyr z-lWwJ(~@HP7l1ZUjV$WpZvfrPF+e`+`au4Ne7wFQy)VRCm&`%nV(=(<3#k1xI#c=o z1;fA=RkTANH`nJj;a*b_b7j9ac8ECmlc_2XNMY@bpYOK6zs~jETtA7UILhweA|QQL z@{<%Z`WevNe^OE#r-0kQFToLD0;rZ0&p8sv|4Gw-l9ZJX5U$7Pn1r^cknD33-f7Cn zo_z!sf(L;7tF3_E30M=X1Z1c5oCr!QZvyxX*cE8Mgww(Afd03OKs9#KCAVym{J9}d z_yG$#ZH8IHXCJHB6O}%EiQx%<{)Yp;$6?w3Q@HLsvZkDSm{GP;Z7;3}`yYcBK-}-7 z@}~ohJ1WJnH>J!oAj)g$=+UDmlds?YG^F>6?*vhPuD()jp6)9tO{HM9?WC=zdp3~0 zl%3)?D}>U@GuPAduBQCGv^V5Q{ms}6=P~}<^|AL3&*N-fW9#Q_5nFf=TwuSWuh{a2 zY2KL|1ft2l>;~k2>lt@Fr+Vfe2PzjO{XWZYQk=n6*W~HtELNXn7qIRvB`N18U$ z9Cc5cOG`qE=`03m_z$PDdM;K;qNu@KM&qU)ebDlUnAcYyNJZLf(dLQ2@zYcc`nj;a zrD)5mH1~Z>KZ{YRIn61K$C4APp&Qqw!E&TN*dr5AFsJgQvj^un_3p;&d6uZ?NT`#yt#a!XNs% z-3Oy-Y{IXfubr-BV`FaZYWI}Zd$Gv3#K>AYPD>}jfRsL$ zR)=!`k*$-B`wjR8SP}GwuA_3)K4{ExCD=BGv3_4QcGdiqY}pCmMlc%;CEflId51I= zzjxYmzYn`#@}Ai_X>XFTPUl)i@lrfI$n?!OH*8sCgV={ncvBVAbT|vca?gG)iH(1YQcU}e80Qo!ku${@vSSQ&W_Fh`_aXa;tRCO$pt_>?r21X7pJ*JSG00!Rt>7wf z8MqzH0aEe?oou_ux>lHs}vZ`J7f1N$Zj(flB_7uFnFRyQ9BkUMi&(Q+og? z&U!t#0-Oi5hT=!yaPTdl_}kY@IFRGP;7D*H&^inGjxHI#Oa3sR2gl&6^jJ&Wy>AjP z33A(|y;*&4!{(zjYaDql-QO}x!@o82W-E5?iELy3F4jGthdp^(V;&+YxDlMAQs3U!~4!(Om&V(!n`%xm(at0L{a zhP{{?+6{ekh;N%=-!9}hC6k$#@Y!d-{UA5jzEA3ZG_HQmrd0_wI4a2()bpB#Hl*-v z!1Y^eKkt>&Ie455hWr?TdvH+;ne8A>5A$4=YLK@UJT(@R9E$C)1cn7=8*@k4{n3@i zcCfE&VV$%$%)Zqdxcn{p{G4nsZ-3O8B1X_Y7JGAw`Bq1#oP6hzy!V=e*SAS3AMIb- zS>MbPHs-HRTECCVtpT53gNMP3U?$M-D)uzA4QFtaADY&-P$d=V_x?%{*T>4`FQeW$ zK!^+`$lj~uec1d%0ZA@i}@|r9?jkNtFE%2V!w8gorv~( zY=QQaemdKb|3Un>e>z5ut$+Q~;l7bUzFWM>@Po&4cpQ~ft=Wd$p4{(JQ(s5L(anCg z`c6_yU16)F{HiRsCH3S(#68z0Uw+DLZ~&+!$(J#0ra3C!F;Zv)ZZyts>`yy1Z1pXB zVE0Q`T0YUZ`qwr~sDx3)eqD@j)Ax5bd*-`&=a(Ua)^`7u;|<_{unqST1M2!lweef5 zBjuKZ;}go1$u_*U9(=ofD~S3Z^9`hfiaa{TF#mS5``t3_k=rNVHIokY+@|U8isO8) zC}U0jDpr(69#i%wHIZg;GOb6fw`25_ADki&EvXoro$9g=jy#^%%5!JfEPXc-+mgG} zyt9uD+Z-Fvb5DB9t~lE3?vvSN`Ie%-XPs2j<1+0l!~dmd8_4uq!-H7aW!lr$oSS1y z=B-cYd$i`f7e~d#UInHfr#YU~i+0OZoxsH85mbR zkY>&E*vza|sMpiy3-XVf*fwLk?^9-ZOH-lSx)Y5V@ynjZJy-MSn?R3m9K5EUsaW zZ;<))Be50B3_tq!OnaZ|V&BePr0>9*GL?>s>EK^YZfR)Siw{{7h`8VzIrYQ(+JnU$CEPS9&>hckZnKj{2*S_YQEinKbWu z2j79n(zt0)a4xt5DBeFC$VMy%nqPVgya_b_t$6{>Jv|8~gL}YT;QvbJTKn@)pt_a* zZ;IEi3VKU*Fkt*2#{G3aBaT`c@?WAa_Si4JXa5cTqDLylN?IG+4~O4Jo%Q*yJ@Z|} zL+$lL(;H+1vQ2IJuIfG5ni={|2yyLqunBLFexCGAT8mVTKhoNe+gE%#WhnVq$TdaZ zeAGX=xDFr}mch<-&Ox-+c`%o7&bY1zBF!9MXD#)2^@F5+J6eu)S2dwu#mKaX z{PV$Azz;zih{|NnRkjffBz=m;Ujdcug^{@y$LnZczVs?U`Y^wh@{?p+J_$AkJAwnj z3E)zob>L5c*+9Dd5NP}-oB0e#9DAVbFre_8&^^a4@na*+^_C^<$k%04j2)1jBX4Rm z-|Dgbj_yokr?l=m&D!Yh95fEZzxxgCb(;qa+Yj>p3;!0?&^ji@i2n@b)7*ciZAIlX z$F~#qYmv$mgF0AwBE_Ssv4>RM4^;c?zeZg>+kH*y6ME)txzvwu2hsM_hbBkLntH0U z8yHAZjL*n3kVol4zR~+Yc0`cB`2kSAt_x{o)Evb|V8l>sQ~SQgW>h*B`*cAzy)3oX z&EJx;-M$M_vIoy-?NZuz!pb!^u0FphKGiR=eQ!tQr%ip^`V1a{6^cCgCUsNpK2r`~ zO|hFyYklr()Gx-bg8XBY=Xb4R6l2ZP;qk|E?U%XsZ(K|B?3uFqjhDTs1>FHt(~gen z9~S`gJ5I72X^qg|fnCR>f6=XE|DW)?R`#8HBj->(exv_YI*=`PjKV*N|E5{QH=B~K^c?y|nv z9JFoIC1tqQ`xaAHa%r8D-t{0IzJD)XEp>D8vzg0huUnmG>*iJ)lU2P+eL!|VzoVKP zo(~j1&VpLdPB2x>$(HF?2^!jjGVey}iN~`E>ejl*S83qSK=B;=zLb`37XaDOTfk-D z9H3Z|($|5%f~P?qECEp-197hLndA!nbdDp2G+#uYt2lSo)rSj96_-w;Agv*!-Zc34 zv`5$t@|QCndW+-J*uz_xr_%cx$IC`xCk|6P_$?=qcR76SF0L<%UxSJ5Tg*KC>D}M2 z?P$R6-3pIR8A#7i?5bOAJ)FQNum{)x zG=q9j2U6H#N|z_uzyrW`U_G!iu-6W#kKP6(V-h-wLaJl;ON}{JPExra%1D3ff-eHy zvtmc;$4PZ6e^BwAHNci&2e22o2iW%_{i1`XHraYCa~|@PQS>tZ-No$yKv7nq6N+LORaB?Uq=|Z7WU(C z4PZyY-_?mLXwM+(T?*!g^&>n}wy!nWk7OI#zCS**sKjg~Mc10G=3DH(5>3zIy8N)T^a(1w32c7)?H}&+2X4^5XOmt?zPCR$`0umV$F}sr z=w5{t?GkmSC|;aSBgQC7q zSNn?ZJwh-*VdSigO3~M|t#;`t)7R4vv)kA=6h}$E$lG=DiW#@&|@9 zY0Nwixb&!TuBRGlfSAaM^h>8LF#Xnf)O=H8+fSGa>&3c~=?y_JZ;kQ1=PH{xp6@&> z)~vnTitDp0+Xj_K{(n?;4~kbYzRNbWE2c73sR_Xq^LF(e<;kZ}d}39QmVQqKo9|N2 z6;m0mq*#u9zjj(<-(6~Oou;hklO?ar0*h{JMh1dHeN`#5HYYL%5#>G*`3)*!{<(3*>(bi~&h0>JKSK zbVSn1eOyj)z@LM&0l$CYw@ow$U?3Z!{Ih_@*oT3y0mYy<2de@7W-9jOBE^ig2FU2k zb<{kaVx;?m{lSmG`9MDB4JAzC_)9PmC{F$T5>DhO`F{)U1o~ge_j(U#4nVpU)UJ+y z1S5>*1@y;9sik+sREQNOk@`3&jdI>?p+XBUbqO<}T2LbgDQ`a2-5-r?M=QlZI zF)}4N%AZ*Z-UPFN;%X0rd%%O>Bannof0g+g@{BmjW)_dv{FbZFrpbfH8{t}<#=_40 zThq+Z#Ohq*rf|-kcR)%uucEJ0NoMwYytdkJfW!(~-G$Lqlb`Y!P(QJsbJ-2~G3$bA zX>}@|3|<1_7v;aCbWQX6iqYNjD7#T*wQGV8lr0|{frrdLt z`f!r#p})c2V;pY-{~zwXx#O$UjT_r=sV1cMM z06T&`!M@-CAYFV991RrPQA|gA`3d-G8Jt-vr?NIw?`)vB(4|2C$KQbKEL=@m@g(^_ zr+{668+uwEH3t&M0)q2MCTz(AV`n#P!pK_lA{Y4r}ZwLMp z+ykBjcY_PTX26rzKtF1rV+GdwokjocRXlhw*e~v3S@HeXLGe3t2LHrLHb^m5jWsR? zs{l`410z}k;l9&B{37)(L(rcijjy+zFW_~L- z(Do+UK0eTgtna?E>pNxX@6Olo8t@tzN*d6dTKkXb`?E9#irR#JJrDBl)82m%@%O}r z(m&tJ>NPOPG|(}I`S7o^=I73&@4NSfjVi`}@-rAKp4pUHu-YI~iWkRgz-wTDG@y6n z6_*LWPh{<#-xqer@WB4e1eZ5A=9yQzRqNC|c@20Ccn!p8V0I&OY&#V91=716xmU3t z#BY*~;lgr^w|EcidHk(wW#5_`7Hq_HlaKAjXxwLe4R{SC(Lk DeviceID{ + {0x3072,0x239}, {0x31c9,0x8200}, #ifdef G200 #ifdef ISG100 + {0x31c9,0x8629}, {0x31c9,0x8620}, #else + {0x31c9,0x8739}, {0x31c9,0x8730}, #endif // ISG100 #elif defined G300 @@ -278,11 +287,17 @@ static std::vector DeviceID{ #endif // ISG100 }; + +#elif defined AUGE +static std::vector DeviceID{ + {0x3072,0x0130}, +}; + #elif defined HANVON static std::vector DeviceID{ - {0x2903,0x7000}, }; + #else static std::vector DeviceID{ {0x64B,0x7823}, @@ -295,7 +310,7 @@ static std::vector DeviceID{ {0x3072,0x200}, #endif // ISG100 #elif defined G300 - {0x3072,0x300}, + {0x3072,0x0300} #elif defined G400 {0x3072,0x400}, #endif // ISG100 @@ -365,51 +380,39 @@ HuagaoDs::HuagaoDs() // //guiIndicator.reset(); // if (!m_memoryfalg) // return; - // MessageBox(NULL, L"ڴ治", L"", MB_OK| MB_SYSTEMMODAL); + // MessageBox(NULL, L"ڴ治", L"ʾ", MB_OK| MB_SYSTEMMODAL); //})); } void HuagaoDs::showmsg(std::string caption, std::string text, int retcode) { if (scanner.get()) { - int num = scanner->get_scannum() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); -//#ifdef G1003399 - int readnum =scanner->get_scannum()* (m_scanparam->is_duplex ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); -//#else -// int readnum = scanner->get_scannum(); -//#endif // G1003399 - - + //int num = scanner->get_scannum() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); + //int readnum =scanner->get_scannum()* (m_scanparam->is_duplex ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); + int num = scanner->get_imgnReaded() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); + int imgread = scanner->get_imgnReaded(); + IScanner* ptr = scanner.get(); + if (typeid(*ptr) == typeid(GScanO1003399)) + { + //readnum = readnum / 2 * (m_scanparam->en_fold ? 2 : 1); + num = scanner->get_imgnReaded() * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); + imgread /= 2; + } if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince)) { - if ((retcode == 64 || retcode == 8 || retcode == 16)) { - num = (scanner->get_scannum()-1) * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); -//#ifdef G1003399 - int readnum = (scanner->get_scannum() -1)* (m_scanparam->is_duplex ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); -//#else -// int readnum = scanner->get_scannum()-1; -//#endif // G1003399 - if (((num - scanner->get_imgTransfered()) > 0)||((readnum-scanner->get_imgnReaded())>0)) { - text += "ֽ" + to_string(scanner->get_scannum()-1) + - "ɨ" + to_string(scanner->get_imgnReaded()) + "ϴ" + to_string(scanner->get_imgTransfered()) + - "ɨ" + to_string(readnum - scanner->get_imgnReaded()) + "ļϴ" + to_string(num - scanner->get_imgTransfered()) + "ļ"; - scanner->set_lose_image_num(0); - } - } - else{ - if (((num - scanner->get_imgTransfered()) != 0) || ((readnum - scanner->get_imgnReaded()) != 0)) { - text += "ֽ" + to_string(scanner->get_scannum()) + - "ɨ" + to_string(scanner->get_imgnReaded()) + "ϴ" + to_string(scanner->get_imgTransfered()) + - "ɨ" + to_string(readnum - scanner->get_imgnReaded()) + "ļϴ" + to_string(num - scanner->get_imgTransfered()) + "ļ"; - scanner->set_lose_image_num(0); - } - } - + text += "\nɨͳϢ\nֽţ" + to_string(scanner->get_scannum()) + + "\nɨ裨ţ" + to_string(imgread) + "\nɨţ" + to_string(scanner->get_scannum() - imgread) + + "\nϴҳ" + to_string(scanner->get_imgTransfered()) + "\nϴҳ" + to_string(num - scanner->get_imgTransfered()); + scanner->set_lose_image_num(0); } } ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString((text + " " + caption).c_str()), NULL, SW_HIDE); } +void HuagaoDs::hgmsg(CString str) +{ + ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE); +} HuagaoDs::~HuagaoDs() { if (memoryinfo.get()) { @@ -803,26 +806,24 @@ void HuagaoDs::dogear_callback(int indexpaper) CString text; text.Format(_T("74 %d"), indexpaper); //ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE); - showmsg("",""+to_string(indexpaper)+"⵽۽ǣ"); + showmsg("ʾ",""+to_string(indexpaper)+"⵽۽ǣ"); scanner->Stop_scan(); //scanner->reset(); scanner->ResetScanner(); onDeviceEvent(DOG_EAR); } - Result HuagaoDs::identityOpenDs(const Identity&) { + hMutex = CreateMutex(NULL, FALSE, _T("LookitApp")); if (GetLastError() == ERROR_ALREADY_EXISTS) { //ѾͬMutexõ. CloseHandle(hMutex); hMutex = NULL; //ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("202"), NULL, SW_HIDE); - showmsg("", msgs[(UsbSupported)202]); + showmsg("ʾ", msgs[(UsbSupported)202]); return { ReturnCode::Failure, ConditionCode::CapBadOperation }; } - - - + Twain_config().GetOrSetPintfCapability(is_printfcapability, true); auto usblist = UsbScan_List::find_all_usb(); if (!usblist.empty()) { @@ -836,12 +837,16 @@ Result HuagaoDs::identityOpenDs(const Identity&) { pid = usb.pid; if (!scanner.get()) { #ifdef G200 - if (pid == 0x139 || pid == 0x239) + if (pid == 0x139 || pid == 0x239 || pid == 0x8739 || pid == 0x8629) scanner.reset(new GScanO1003399()); else scanner.reset(new GScanO200()); +#else +#ifdef ANDROIDSERIAL + scanner.reset(new GScanO400Android()); #else scanner.reset(new GScanO400()); +#endif #endif // G400 break; } @@ -854,8 +859,8 @@ Result HuagaoDs::identityOpenDs(const Identity&) { if (vid == 0 || pid == 0) { //ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE); - //showmsg("", msgs[(UsbSupported)201]); - ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("δҵɨ!ԴUSBǷͨ! "), NULL, SW_HIDE); + //showmsg("ʾ", msgs[(UsbSupported)201]); + ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("δҵɨ!ԴUSBǷͨ! ʾ"), NULL, SW_HIDE); if (hMutex) { CloseHandle(hMutex); hMutex = NULL; @@ -869,12 +874,12 @@ Result HuagaoDs::identityOpenDs(const Identity&) { CloseHandle(hMutex); hMutex = NULL; } - showmsg("", msgs[(UsbSupported)81]); + showmsg("ʾ", msgs[(UsbSupported)81]); return seqError(); } if (!scanner->IsConnected()) { //ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE); - showmsg("", msgs[(UsbSupported)201]); + showmsg("ʾ", msgs[(UsbSupported)201]); if (hMutex) { CloseHandle(hMutex); hMutex = NULL; @@ -887,7 +892,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { auto dgcall = [&](int pagenum) { //ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE); - showmsg("", "" + to_string(pagenum) + "⵽۽ǣ"); + showmsg("ʾ", "" + to_string(pagenum) + "⵽۽ǣ"); scanner->Stop_scan(); //scanner->reset(); scanner->ResetScanner(); @@ -931,6 +936,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::DeviceOnline] = msgSupportGetAll; //m_caps[CapType::DeviceOnline] = std::bind(enmGet, _1, _2, Bool(scanner->IsConnected())); m_caps[CapType::DeviceOnline] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapType::DeviceOnline)); switch (msg) { case Msg::Get: case Msg::GetCurrent: @@ -945,6 +951,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::XferCount] = msgSupportGetAllSetReset; m_caps[CapType::XferCount] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapType::XferCount),msg==Msg::Set?to_string((int)data.currentItem()):""); if (msg == Msg::Set) { auto item = data.currentItem(); if (item > 65535 || item < -1 || item == 0) { @@ -964,8 +971,8 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::ICompression] = msgSupportGetAllSetReset; //m_caps[CapType::ICompression] = std::bind(enmGetSetConst, _1, _2, Compression::None); - m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result - { + m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result{ + CapabilityPrintf(msg, enum2str(CapType::ICompression), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); if (Compression::None == mech || mech == Compression::Group4) { @@ -980,6 +987,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IBitDepth] = msgSupportGetAllSetReset; m_caps[CapType::IBitDepth] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapType::IBitDepth), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); if (((mech == 1) && (m_scanparam->pixtype == 0)) || ((mech == 8) && (m_scanparam->pixtype == 1)) || ((mech == 24) && (m_scanparam->pixtype == 2))) { @@ -1008,15 +1016,16 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IPixelType] = msgSupportGetAllSetReset; m_caps[CapType::IPixelType] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapType::IPixelType), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if( Msg::Set==msg) { auto mech = data.currentItem(); if (mech == PixelType::Rgb || mech == PixelType::Gray || mech == PixelType::BlackWhite) { + m_scanparam->automaticcolor = FALSE; m_scanparam->pixtype = (int)mech; if (m_scanparam->pixtype == (int)PixelType::Rgb){ m_scanparam->filter = (BYTE)Filter::None; - m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None; - m_scanparam->automaticcolor = FALSE; + m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None; } else{ m_scanparam->multi_output_red = 0;//Dzɫģʽ¶ @@ -1043,6 +1052,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IAutomaticColorEnabled] = msgSupportGetAllSetReset; m_caps[CapType::IAutomaticColorEnabled] = [this](Msg msg, Capability& data)->Result { + CapabilityPrintf(msg, enum2str(CapType::IAutomaticColorEnabled), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); if (mech) { @@ -1061,6 +1071,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IAutomaticColorNonColorPixelType] = msgSupportGetAllSetReset; m_caps[CapType::IAutomaticColorNonColorPixelType] = [this](Msg msg, Capability& data)->Result { + CapabilityPrintf(msg, enum2str(CapType::IAutomaticColorNonColorPixelType), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (msg == Msg::Set) { auto mech = data.currentItem(); if (m_scanparam->automaticcolor == TRUE) { @@ -1076,9 +1087,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //add------------------jpegȼ--------------------- m_query[CapType::IJpegQuality] = msgSupportGetAllSetReset; m_caps[CapType::IJpegQuality] = [this](Msg msg, Capability& data)->Result { + CapabilityPrintf(msg, enum2str(CapType::IJpegQuality), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); - if ((int)mech < 0 || (int)mech > 100) + if ((int)mech <= 0 || (int)mech > 100) return badValue(); m_jpegQuality = (int)mech; return success(); @@ -1091,6 +1103,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IXferMech] = msgSupportGetAllSetReset; m_caps[CapType::IXferMech] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapType::IXferMech), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); if (mech == XferMech::Native || mech == XferMech::Memory || mech == XferMech::File) { @@ -1106,6 +1119,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IXResolution] = msgSupportGetAllSetReset; m_caps[CapType::IXResolution] = [this](Msg msg, Capability& data) { + CapabilityPrintf(msg, enum2str(CapType::IXResolution), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); switch (msg) { case Msg::Get: data = Capability::createRange(Fix32(100.0f), Fix32(600.0f), Fix32(1.0f), Fix32(m_scanparam->resolution_dst), Fix32(200.0)); @@ -1141,9 +1155,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::ISupportedSizes] = msgSupportGetAllSetReset; m_caps[CapType::ISupportedSizes] = [this](Msg msg, Capability& data) { + CapabilityPrintf(msg, enum2str(CapType::ISupportedSizes), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { - if (m_scanparam->is_autocrop) - return success(); + //if (m_scanparam->is_autocrop) + // return success(); auto paper = data.currentItem(); if (std::distance(paperSizeList.begin(), std::find(paperSizeList.begin(), paperSizeList.end(), paper)) == paperSizeList.size()) return badValue(); @@ -1188,7 +1203,11 @@ Result HuagaoDs::identityOpenDs(const Identity&) { #ifndef ISG100 m_query[(CapType)(CapTypeEx::TwEx_SizeDetect)] = msgSupportGetAllSetReset; m_caps[(CapType)(CapTypeEx::TwEx_SizeDetect)] = [this](Msg msg, Capability& data)->Result { + CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_SizeDetect), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { + if (m_scanparam->papertype == (uint8_t)PaperSize::None || m_scanparam->papertype == (uint8_t)PaperSize::MaxSize || m_scanparam->papertype == (uint8_t)PaperSize::UsStatement || + m_scanparam->papertype == (uint8_t)PaperSizeEx::Trigeminy) + return badValue(); auto mech = data.currentItem(); m_scanparam->en_sizecheck = mech; return success(); @@ -1200,8 +1219,13 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IOrientation] = msgSupportGetAllSetReset; m_caps[CapType::IOrientation] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapTypeEx::IOrientation), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); if (Msg::Set == msg) { auto mech = data.currentItem(); + if ((mech == Orientation::Landscape) && (m_scanparam->papertype == (uint8_t)PaperSize::None || m_scanparam->papertype == (uint8_t)PaperSize::MaxSize || + m_scanparam->papertype == (uint8_t)PaperSize::UsStatement || m_scanparam->papertype == (uint8_t)PaperSizeEx::Trigeminy || m_scanparam->papertype == (uint8_t)PaperSize::A3 || + m_scanparam->papertype == (uint8_t)PaperSize::IsoB4 || m_scanparam->papertype == (uint8_t)PaperSizeEx::K8 || m_scanparam->papertype == (uint8_t)PaperSize::UsLedger)) + return badValue(); if (mech == Orientation::Landscape || mech == Orientation::Portrait) { m_scanparam->paperAlign = (PaperAlign)mech; return success(); @@ -1213,6 +1237,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_query[CapType::IRotation] = msgSupportGetAllSetReset; m_caps[CapType::IRotation] = [this](Msg msg, Capability& data) -> Result { + CapabilityPrintf(msg, enum2str(CapTypeEx::IRotation), msg == Msg::Set ? to_string((float)data.currentItem()) : ""); if (Msg::Set == msg) { auto res = data.currentItem(); if (std::distance(imageRotateList.begin(), std::find(imageRotateList.begin(), imageRotateList.end(), res)) == imageRotateList.size()) @@ -1260,11 +1285,13 @@ Result HuagaoDs::identityOpenDs(const Identity&) { #endif 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; @@ -1286,6 +1313,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1299,13 +1327,15 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { - auto mech = data.currentItem(); + bool mech = data.currentItem(); m_scanparam->is_duplex = mech; - if (!mech) + if (!mech){ m_scanparam->is_backrotate180 = 0;//汳ת180㲻 - else + 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)); @@ -1313,6 +1343,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1322,6 +1353,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { }; 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 || @@ -1340,6 +1372,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //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; @@ -1350,10 +1383,13 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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 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); @@ -1361,6 +1397,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1378,6 +1415,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1389,6 +1427,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { @@ -1415,6 +1454,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { @@ -1451,6 +1491,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1467,6 +1508,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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)) @@ -1498,15 +1540,15 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //հҳƱ 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; - } - if (mech) m_scanparam->is_autodiscradblank_normal = 0; + } return success(); } return CapSupGetAllResetEx(msg, data, m_scanparam->is_autodiscradblank_vince, false); @@ -1516,11 +1558,13 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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(); - m_scanparam->is_backrotate180 = mech; - if (mech) - m_scanparam->is_duplex = 1; + if (m_scanparam->is_duplex && mech) + m_scanparam->is_backrotate180 = mech; + else + return badValue(); return success(); } return CapSupGetAllResetEx(msg, data, m_scanparam->is_backrotate180, false); @@ -1530,6 +1574,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //ڿ 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; @@ -1542,6 +1587,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //üƫ 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)) @@ -1555,9 +1601,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //Զü 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 > 10 || mech < 0) && ((bool)m_scanparam->is_autocrop == true)) + if ((mech > 20 || mech < 0) && ((bool)m_scanparam->is_autocrop == true)) return badValue(); m_scanparam->noise = mech; return success(); @@ -1567,10 +1614,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //Զк;ƫĶֵֵ 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) && ((bool)m_scanparam->is_autocrop == true)) + if (mech > 50 || mech < 30) return badValue(); m_scanparam->AutoCrop_threshold = mech; return success(); @@ -1580,6 +1627,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //ڿ䷽ʽ 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; @@ -1590,6 +1638,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { // 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; @@ -1601,6 +1650,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { @@ -1614,6 +1664,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //Ż 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) { if (m_scanparam->pixtype != 0) return badValue(); @@ -1627,6 +1678,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { @@ -1640,12 +1692,14 @@ Result HuagaoDs::identityOpenDs(const Identity&) { // 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->multi_output_red = mech; else - m_scanparam->multi_output_red = 0;//Dzɫ ʹö + return badValue(); + //m_scanparam->multi_output_red = 0;//Dzɫ ʹö return success(); } return CapSupGetAllResetEx(msg, data, m_scanparam->multi_output_red, false); @@ -1654,8 +1708,11 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //⿨ 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 && m_scanparam->pixtype != (int)PixelType::Rgb) + return badValue(); m_scanparam->hsvcorrect = mech; return success(); } @@ -1665,9 +1722,12 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1682,6 +1742,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //ɫǿ 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) @@ -1697,14 +1758,6 @@ Result HuagaoDs::identityOpenDs(const Identity&) { m_scanparam->enhance_color = (BYTE)mech; if (mech != (BYTE)Enchace_Color::Enhance_None) m_scanparam->filter = (BYTE)Filter::None; - - //if (m_scanparam->pixtype == (int)PixelType::BlackWhite) - //{ - // if (m_scanparam->enhance_color == (BYTE)Enchace_Color::Enhance_None) - // { - // m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_Red; - // } - //} return success(); } } @@ -1715,6 +1768,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) @@ -1729,6 +1783,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { /* Աȶ 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)); @@ -1755,6 +1810,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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)); @@ -1781,6 +1837,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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)); @@ -1808,6 +1865,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { /*ΪӲЭ*/ 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; @@ -1820,6 +1878,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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) { @@ -1834,6 +1893,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //װ 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; @@ -1843,9 +1903,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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; @@ -1853,9 +1914,25 @@ Result HuagaoDs::identityOpenDs(const Identity&) { } 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, 50); + }; + //˫ż ٷ׼ Э޸Ϊ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); @@ -1889,6 +1966,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { //͹ģʽ 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; @@ -1903,6 +1981,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { 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 || @@ -1920,6 +1999,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) { #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)); @@ -1991,11 +2071,11 @@ Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) { if (ret != -1) { int index = scanner->geterrorindex(); if (ret == 82) - showmsg("", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", ret); + showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", ret); else if(ret==75) - showmsg("", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", ret); + showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", ret); else - showmsg("", msgs[(UsbSupported)ret], ret); + showmsg("ʾ", msgs[(UsbSupported)ret], ret); FileTools::writelog(log_ERROR, msgs[(UsbSupported)ret]); #ifndef G200 scanner->clear_hwerror(); @@ -2008,7 +2088,7 @@ Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) { int num = scanner->get_scannum() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1); if ((num - scanner->get_imgTransfered()) != 0) { - showmsg("", msgs[LOSE_IMAGE]); + showmsg("ʾ", msgs[LOSE_IMAGE]); FileTools::writelog(log_ERROR, msgs[LOSE_IMAGE]); } @@ -2394,7 +2474,7 @@ Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly) while (!scanner->Get_Scanner_PaperOn()) { if (scanner->get_ErrorCode() == SLEEPING) { - showmsg("", msgs[(UsbSupported)81]); + showmsg("ʾ", msgs[(UsbSupported)81]); scanner->Set_ErrorCode(0); return seqError(); } @@ -2461,6 +2541,32 @@ void HuagaoDs::DeviceEvent_callback(int eventID, void* 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)) @@ -2520,59 +2626,30 @@ Twpp::Result HuagaoDs::startScan() scanner->ResetScanner(); scanner->reset(); - //std::string info = "ʼɨ ===> ɨòΪ\n\t m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop); - //info += "\n\t m_scanparam->colorenable :" + to_string(m_scanparam->automaticcolor); - //info += "\n\t m_scanparam->colorenabletype :" + to_string(m_scanparam->automaticcolortype); - //info += "\n\t m_scanparam->papertype :" + to_string(m_scanparam->papertype); - //info += "\n\t m_scanparam->fillbackground :" + to_string(m_scanparam->fillbackground); - //info += "\n\t m_scanparam->autodescrew :" + to_string(m_scanparam->autodescrew); - //info += "\n\t m_scanparam->brightness :" + to_string(m_scanparam->brightness); - //info += "\n\t m_scanparam->Caption :" + m_scanparam->Caption; - //info += "\n\t m_scanparam->contrast :" + to_string(m_scanparam->contrast); - //info += "\n\t m_scanparam->discardblank_percent :" + to_string(m_scanparam->discardblank_percent); - //info += "\n\t m_scanparam->enhance_color :" + to_string(m_scanparam->enhance_color); - //info += "\n\t m_scanparam->en_fold :" + to_string(m_scanparam->en_fold); - //info += "\n\t m_scanparam->hardwarecaps.capturepixtype :" + to_string(m_scanparam->hardwarecaps.capturepixtype); - //info += "\n\t m_scanparam->hardwarecaps.en_doublefeed :" + to_string(m_scanparam->hardwarecaps.en_doublefeed); - //info += "\n\t m_scanparam->hardwarecaps.en_stapledetect :" + to_string(m_scanparam->hardwarecaps.en_stapledetect); - //info += "\n\t m_scanparam->hardwarecaps.en_skrewdetect :" + to_string(m_scanparam->hardwarecaps.en_skrewdetect); - //info += "\n\t m_scanparam->hardwarecaps.skrewdetectlevel :" + to_string(m_scanparam->hardwarecaps.skrewdetectlevel); - //info += "\n\t m_scanparam->imageRotateDegree :" + to_string(m_scanparam->imageRotateDegree); - //info += "\n\t m_scanparam->is_duplex :" + to_string(m_scanparam->is_duplex); - //info += "\n\t m_scanparam->pixtype :" + to_string(m_scanparam->pixtype); - //info += "\n\t m_scanparam->resolution_dst :" + to_string(m_scanparam->resolution_dst); - //info += "\n\t m_scanparam->resolution_native :" + to_string(m_scanparam->resolution_native); - //info += "\n\t m_scanparam->paperAlign :" + to_string((int)m_scanparam->paperAlign); - //info += "\n\t m_scanparam->gamma :" + to_string(m_scanparam->gamma); - //info += "\n\t m_scanparam->threshold :" + to_string(m_scanparam->threshold); - //info += "\n\t m_scanparam->is_autocontrast :" + to_string(m_scanparam->is_autocontrast); - //info += "\n\t m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop); - //info += "\n\t m_scanparam->fillhole.fillholeratio :" + to_string(m_scanparam->fillhole.fillholeratio); - //info += "\n\t m_scanparam->fillhole.is_fillhole :" + to_string(m_scanparam->fillhole.is_fillhole); - //info += "\n\t m_scanparam->is_autodiscradblank_normal :" + to_string(m_scanparam->is_autodiscradblank_normal); - //info += "\n\t m_scanparam->is_autodiscradblank_vince :" + to_string(m_scanparam->is_autodiscradblank_vince); - //info += "\n\t m_scanparam->is_switchfrontback :" + to_string(m_scanparam->is_switchfrontback); - //info += "\n\t m_scanparam->multi_output_red :" + to_string(m_scanparam->multi_output_red); - //info += "\n\t m_scanparam->hsvcorrect :" + to_string(m_scanparam->hsvcorrect); - //info += "\n\t m_scanparam->filter :" + to_string(m_scanparam->filter); - //info += "\n\t m_scanparam->sharpen :" + to_string(m_scanparam->sharpen); - //info += "\n\t m_scanparam->scannum :" + to_string(m_scanparam->scannum); - //info += "\n\t m_scanparam->is_backrotate180 :" + to_string(m_scanparam->is_backrotate180); - //info += "\n\t m_scanparam->is_autotext :" + to_string(m_scanparam->is_autotext); - //info += "\n\t m_scanparam->SavePath :" + m_scanparam->SavePath; - //info += "\n\t m_scanparam->noise :" + to_string(m_scanparam->noise); - //info += "\n\t m_scanparam->indent :" + to_string(m_scanparam->indent); - //info += "\n\t m_scanparam->AutoCrop_threshold :" + to_string(m_scanparam->AutoCrop_threshold); - //info += "\n\t m_scanparam->is_convex :" + to_string(m_scanparam->is_convex); - //FileTools::write_log("D:\\1.txt",info); FileTools::writelog(log_INFO, "start scan"); -#ifndef G200 - if(scanner->notifyscan()<1) +#ifdef G200 +#ifndef ANDROIDSERIAL + if (scanner->notifyscan() < 1) return seqError(); - +#endif // !ANDROIDSERIAL scanner->clear_hwerror(); +#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()); + } + } -#endif // scanner->config_params(*m_scanparam); @@ -2618,11 +2695,11 @@ Twpp::Result HuagaoDs::startScan() //ShellExecute(guiTwain ? guiTwain->m_hWnd : NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE); int index = scanner->geterrorindex(); if (retCode == 82) - showmsg("", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", retCode); + showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽۽ǣֹͣɨ裡", retCode); else if (retCode == 75) - showmsg("", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", retCode); + showmsg("ʾ", "ڵ" + to_string(index) + "ҳ⵽ߴ粻ֹͣɨ裡", retCode); else - showmsg("", msgs[(UsbSupported)retCode], retCode); + showmsg("ʾ", msgs[(UsbSupported)retCode], retCode); FileTools::writelog(log_ERROR, msgs[(UsbSupported)retCode]); #ifndef G200 scanner->clear_hwerror(); diff --git a/huagao/huagaods.hpp b/huagao/huagaods.hpp index 7696b307..40cc3925 100644 --- a/huagao/huagaods.hpp +++ b/huagao/huagaods.hpp @@ -94,7 +94,9 @@ private://method void dogear_callback(int indexpaper); void updataGscanCap(); Twpp::Result capCommon(const Twpp::Identity& origin, Twpp::Msg msg, Twpp::Capability& data); + void CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value = ""); void showmsg(std::string caption, std::string text, int retcode=0); + void hgmsg(CString str); private://field std::unordered_map> m_caps; @@ -127,7 +129,7 @@ private://field bool m_memoryfalg = true; HANDLE hMutex; int pid = 0, vid = 0; - + int is_printfcapability; }; #endif // SIMPLEDS_HPP diff --git a/huagao/huagaotwds.rc b/huagao/huagaotwds.rc index cd08bf999441356a5502b21772e346eac10d309d..f98e80197b89d8f2a3658f9796ab45ac877e3375 100644 GIT binary patch delta 2245 zcmZuzO>7%g5S~p_H!;ReN?gYV{F74Jq^8;Rdi^6IAt$Lqp!L7wMufN~33aN*Eh!;L zw73Ows7g`kLzQqv5QicTAPSa{ka|Z#pbEi-3#dW`i33u(a6pNfdCzNmakP@(?%Ovr z-#7EktiS!S>(i~STTgn}+sTp9x!L{4hrkb0FahIGfHBBI9M>4GSxDpl7|h_^VLTIo zFxwn-vOOPo*_n5C*UFy1HA!a0+`1&!{>b(2WG_s)*qnW+=6~)niQS5gu;j$xg9UV* zfJt-_gEZURyULRJZij{r6$s!ZR++CFOW8+RHSf03ei%cFw;}eKJ<7K7ZU^lLAPC}o z0LYIDDyuAeYA?>`>})ljrKkbFMmbmE86WB$4Z3WKGzKK>+dH z9f&@qAZi)T;I#~+xJyq<{K*Rk8qW*(yac|Jw!#DPA2!avvQ$`k!;&TU!^~Oo_*&jY z<`j&94$apDv>7=80M)jjY>HR2T^_rT!n$B zWkBT;29!|Z6BM+q>#1_(`-R!Wzvq5^y~9jsN&G6Dx`y$Px_NX_nt!SKNm`gVTahR~ zdL$J>1kOr_jWOD4LV#K(8UpiU-gp#~wyG!CU_j;5V~C73l5E<%;J6?l84N_-bvCp% z49o=U^RsUr6GjiWcqlweA_~b)BPQ&Z@j>Pr2=|Z^|ADKy2 zNJ%~QG(3ap)u6X7$vMO}h8zzeH%ZRo#G)2_0>-Ij4Bqwf6El<>&wT@+Cx}Dp0E&*p zH;nQNp?})R;57lf{r0uUitG?hQ9+@^CRXbaY~wPl!mB`Pq)fFXTAzEmvCw0PePP!g z%EB5Hxv?Z?@U9Gt|D%EPgag;DQJVN1f&i&GxyEf5;57OJ`3E{jd+K{xrUeAXa|g5usg`yn}cF8nex*AyXMf&~t>ZDrEzQ{Bj5HcKzuc78Shv zj_{8LDSHytyiIF}aU^JpdEAs6OQyPe{)}JF|C15j-!}0TE)UWD#G`?lSxV-e^a;uk zN`pAX5TnmCRfXmg^+;ve@#R}?`?c!>+k8u7@2&5^#IlQ*?CdZ02>a>EZg%Rrx#oWV zb{G4uIv^?RZuKa;eZ#V=0H;u#C)n53{Zf#2`-|8oCtwl(cknlGy7tYD^QP^;+O_*1 H{k-cxgqYBj delta 110 zcmV-!0FnQ!{sPL=0eHIp6}E|WM`AOSJ6Syl-JlQJ9{ zlU@}fvz}Wd0kd>oZVnMO05t$C0673Q04xA905AYFv+-;(8ME$|9uLM;tKqz(iKN*%=$drUSJRG_K_L6lO|t}6Nh6$)ivx83lD>m5L)C@ZY1EfpztouaHc*>F{ixWHo_fvXF+v U zL(Swu1JTI|rficvI2B|R7#tb=7+e^F82lMLfpjoXeGri4$l${;*^W_W@;XkQ$xfUd zlY=2uwbu>LlsNPzrQpD$wF&hD3%u27RFMV3Em3WTS(*P-b8Y|`ZHq0t`Luzqcc!x2A1rUA@u4}wE zLpo?f>f1192JVc>3QA6s9gJ8u?~>UiIeCwa7~H9btfG@Am}yPkV-&Vo!Q6s*bC#JH z%j7Obfyo#2d2F45&i7+*13KHCAs*=bU@%_+?BEC>sllKG42XPSK%_BbGNd!;F=R0m OgZWAfnw!h5Oc?=aXMwT+ delta 90 zcmV-g0Hy!rjsdK9u!IN&GypIFFq7{z8I#mG5|f?|4wJ$NY?I;%oC7ZaFOv}(6SI^G w@)DDb4iJ-=Cm55U7Id@FBnBCikP8HpFbf2eMg$a-&@?2o3PQ{Svp7a90kF>=ssI20