调整twain协议

This commit is contained in:
masayume 2021-11-20 11:09:04 +08:00
parent a74735c8d8
commit e7c4c666f6
48 changed files with 2095 additions and 428 deletions

11
changelog.txt Normal file
View File

@ -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.更新穿孔算法

View File

@ -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);

View File

@ -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);

46
huagao/CAttributeDlg.cpp Normal file
View File

@ -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: 在此添加控件通知处理程序代码
}

25
huagao/CAttributeDlg.h Normal file
View File

@ -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();
};

View File

@ -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<CString> 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();
}

View File

@ -55,4 +55,5 @@ private:
public:
afx_msg void OnCbnSelchangeCblowpowermode();
afx_msg void OnNMReleasedcaptureSliderdpi(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBnClickedBtnAttribyte();
};

View File

@ -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);
}

View File

@ -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();
};

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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:
/// 设置本批次扫描的样张数量
/// </summary>
/// <param name="val">样张数量</param>
void set_scannum(int val) { scannum = val; };
void set_scannum(int val) {
scannum = val;
};
/// <summary>
/// 获取本批次扫描的样张数量
/// </summary>
/// <returns>样张数量</returns>
int get_scannum() { return scannum; };
int get_scannum() {
return scannum;
};
/// <summary>
/// 获取PC获取的图像数量页计数
/// </summary>
/// <returns></returns>
int get_imgnReaded() { return imgreadednum; };
int get_imgnReaded() {
return imgreadednum;
};
/// <summary>
/// 获取图像传输张数
/// </summary>
/// <returns></returns>
int get_imgTransfered() { return imgtransfered; };
int get_imgTransfered() {
return imgtransfered;
};
/// <summary>
/// 获取丢失图像张数
/// </summary>
/// <returns></returns>
int get_lose_image_num() { return lose_image_num; };
int get_lose_image_num() {
return lose_image_num;
};
/// <summary>
/// 设置丢失图像张数
/// </summary>
/// <param name="value"></param>
void set_lose_image_num(int value) { lose_image_num = value; };
void set_lose_image_num(int value) {
lose_image_num = value;
};
/// <summary>
/// 获取原始图像计数自加一
/// </summary>
@ -263,7 +274,6 @@ protected:
int roller_num;
int scannum;
int lose_image_num;
bool is_Android;
int error_index;
};

View File

@ -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(&param39, 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<std::vector<char>>& 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;//只处理自动文本方向识别 其他的不处理
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)
{

View File

@ -83,6 +83,7 @@ private:
BlockingQueue<std::string> m_paths;
//std::queue<std::future<void>> fu_imgpro;
std::shared_ptr<CImageApplyRotation> m_autotext;
std::shared_ptr <std::thread> m_imgprocthread;
std::shared_ptr<std::thread> m_usbthread;
std::shared_ptr<std::vector<char>> im_data;

View File

@ -446,7 +446,7 @@ void GScanO200::Scanner_StartScan(UINT16 count)
int GScanO200::notifyscan()
{
return -1;
return 1;
}
void GScanO200::Stop_scan()

View File

@ -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,8 +656,6 @@ void GScanO400::usbmain()
#else
UpdateScanInfo(countNReaded(), get_imgTransfered());
#endif
if (!is_Android)
Pop_Image();
FileTools::writelog(log_INFO, "从扫描仪接收" + to_string(get_imgnReaded()) + "份文件。耗时 " + to_string(sw.elapsed_ms()));
sw.reset();
@ -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<std::vector<char>> GScanO400::Get_Img_Data(int bufferSize)
return std::shared_ptr<std::vector<char>>(new std::vector<char>());
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(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 };

View File

@ -1,7 +1,7 @@
#pragma once
#include "GScan.h"
#include <memory>
#include "StopWatch.h"
class GScanO400 : public IScanner
{

View File

@ -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,
//设置扫描仪编码
GET_CODE_G400 = 0x59,
//读取扫描仪编码
SET_CODE_G400 = 0x60,
//设置扫描仪编码
SET_CODE_G200 = 0x63,
//读取扫描仪编码
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<void(int)> 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<unsigned char>& 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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(&notify, sizeof(notify));
//m_usb->read_bulk(&notify, 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::vector<char>> 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<IDecode>(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<IDecode>(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<std::vector<char>> GScanO400Android::Get_Img_Data(int bufferSize)
{
try
{
bool ZLP = false;
if (!(m_usb.get() && m_usb->is_connected()))
return std::shared_ptr<std::vector<char>>(new std::vector<char>());
if ((bufferSize & 511) == 0)
{
bufferSize += 1;
ZLP = true;
}
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(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));
}

View File

@ -0,0 +1,59 @@
#pragma once
#include "GScan.h"
#include <memory>
#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<unsigned char>& 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<void(int)> 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<std::vector<char>> Get_Img_Data(int buffersize);
void Pop_Image();
private:
bool m_bread_fixed_ratio_fromDSP;
std::shared_ptr<IUsb> m_usb;
std::unique_ptr<thread> m_threadUsb;
GScanCap gcap;
volatile int image_num;
volatile bool scanfalg;
volatile bool image_last;
void* huagods;
deviceevent_callback dev_callback;
};

View File

@ -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<CImageApply>(new CImageOutHole(200, ratio, 50)));
m_iaList.push_back(shared_ptr<CImageApply>(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<CImageApply>(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<CImageApply>(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<CImageApply>(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<CImageApply>(new CImageApplyDiscardBlank()));
CImageApplyDiscardBlank* disBlank = new CImageApplyDiscardBlank();
@ -228,6 +213,25 @@ void ImageMatQueue::setparam(const GScanCap& param)
//m_iaList.push_back(shared_ptr<CImageApply>(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<CImageApply>(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<CImageApply>(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<CImageApply>(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<CImageApply>(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn)));
delete[] chRtn;
}
}
void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr<std::vector<unsigned char>> 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<cv::RotatedRect> rects;
std::vector<int> 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<CImageApplyRotation*>(ptr)->angleResults();
}
#ifdef UV
if (!uvmats.empty())
{

View File

@ -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<std::vector<unsigned char>>(new std::vector<unsigned char >());
int headsize = 62;
int width = mat.cols;

View File

@ -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) });

View File

@ -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

View File

@ -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字节做协议扩展*/
};

View File

@ -3,7 +3,320 @@
#include <tchar.h>
#include <winioctl.h>
#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<std::shared_ptr<IUsb>> UsbScan_List::find_all()
{
auto devs = find_all_usb();
std::list<std::shared_ptr<IUsb>> usbs;
for (auto inter = devs.begin(); inter != devs.end(); inter++) {
usbs.push_back(std::shared_ptr<IUsb>(new UsbScanEx(inter->index)));
}
return usbs;
}
std::list<std::shared_ptr<IUsb>> UsbScan_List::find_vid_pid(int vid, int pid)
{
auto devs = find_all_usb();
std::list<std::shared_ptr<IUsb>> usbs;
for (auto inter = devs.begin(); inter != devs.end(); inter++) {
if (inter->vid == vid && inter->pid == pid)
usbs.push_back(std::shared_ptr<IUsb>(new UsbScanEx(inter->index)));
}
return usbs;
}
std::list<usb_scan_dev_info> 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<usb_scan_dev_info> 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<usb_scan_dev_info> UsbScan_List::find_all_usb()
return usbs;
}
#endif // ANDROIDSERIAL

View File

@ -3,7 +3,7 @@
#include <Windows.h>
#include <usbscan.h>
#endif // WINDOWS
#include <mutex>
#include <memory>
#include <list>
#include "IUsb.h"

View File

@ -8,6 +8,7 @@
#include <log4cplus/log4cplus.h>
#include "PublicFunc.h"
#define enum2str(R) #R
enum log_lv :int {
log_TRACE = 0,

View File

@ -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<GScanCap> 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<GScanCap> 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<GScanCap> 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<GScanCap> 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<GScanCap> 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;
}

View File

@ -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;
};

View File

@ -53,7 +53,6 @@ cv::Mat concatenateMatrix(const cv::Mat& first, const cv::Mat& second)
return mul_r;
}
std::vector<cv::Mat> comMat()
{
std::vector<cv::Mat> mats;
@ -61,14 +60,9 @@ std::vector<cv::Mat> comMat()
srcTri[0] = cv::Point2f(1, 1);
srcTri[1] = cv::Point2f(1, 0);
srcTri[2] = cv::Point2f(0, 1);
const float fact = 0.1f;
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<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
@ -134,7 +135,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
if (m_maxContour.size() == 0)
{
thre.release();
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǹ̶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD>к<EFBFBD>ijߴ<EFBFBD>
//
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<int>(a * p.x + b * p.y + c);
p.y = static_cast<int>(d * p.x + e * p.y + f);
}
for (std::vector<cv::Point>& sub : contours)
for (cv::Point& p : sub)
{
p.x = static_cast<int>(a * p.x + b * p.y + c);
p.y = static_cast<int>(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();
//<2F><><EFBFBD><EFBFBD>ǹ̶<C7B9><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2>к<EFBFBD>ijߴ<C4B3>
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<cv::Mat>& mats, bool isTwoSide)
{
if (mats.empty()) return;

View File

@ -11,7 +11,18 @@
2020/10/28 v1.2.2 BUG
2020/10/29 v1.2.3 0°
2020/11/30 v1.3.0 稿
* 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<cv::RotatedRect>& rotatedROIs() { return m_rects; }

View File

@ -37,6 +37,7 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
//20.12.29 修改参数为51 10 30 235
//20.12.30 修改参数为51 20 30 235
// ╨Й╬╒╨з╟в 51 41 30 245
// 修改参数为17 20 110 235
cv::Mat integ;
int blockSize = 17;//邻域尺寸

View File

@ -24,7 +24,7 @@ CImageApplyDogEarDetection::~CImageApplyDogEarDetection()
}
void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side)
void CImageApplyDogEarDetection::apply(cv::Mat& pDib, int side)
{
m_result = false;
(void)side;
@ -37,6 +37,10 @@ void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side)
cv::Mat thre;
hg::threshold_Mat(src, thre, m_threshold);
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));
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
@ -60,8 +64,9 @@ void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side)
}
}
void CImageApplyDogEarDetection::apply(std::vector<cv::Mat> &mats, bool isTwoSide)
void CImageApplyDogEarDetection::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
(void)mats;
(void)isTwoSide;
}

View File

@ -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:
/// <param name="zoom">原图缩放比例对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放)</param>
/// <param name="distance">理论顶点到实际轮廓最小距离的阈值大于该阈值则判定为折角默认值50像素</param>
CImageApplyDogEarDetection(double threshlod, double zoom = 1.0, double distance = 50);
void setdistance(double distance) { m_distance = distance; }
virtual ~CImageApplyDogEarDetection(void);
/// <summary>
@ -54,3 +55,4 @@ private:
};
#endif // IMAGE_APPLY_DOGEAR_DETECTION_H

View File

@ -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 CImageOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
void CImageApplyOutHole::apply(std::vector<cv::Mat>& 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<cv::Mat>& 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<cv::Mat>& 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<cv::Mat>& 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<std::vector<cv::Point>> contours_mask;
std::vector<cv::Vec4i> 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<std::vector<cv::Point>> contours_mask;
std::vector<cv::Vec4i> b1_mask;
hg::findContours(mask, contours_mask, b1_mask, cv::RETR_TREE); //提取重叠图像轮廓
//过滤非孔洞的联通区域
std::vector<std::vector<cv::Point>> 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<int>(i), cv::Scalar(127), 2);
//for (size_t i = 0; i < hole_contours.size(); i++)
// cv::drawContours(mask, hole_contours, static_cast<int>(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<std::vector<cv::Point>> 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<cv::Point> 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<std::vector<cv::Point>> 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<int>(rrect_front.size.width + rrect_back.size.width) / 2, static_cast<int>(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<std::vector<cv::Point>> CImageOutHole::filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m,
std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m,
cv::RotatedRect roi, float edgeScale, float areaThreshold)
{
edgeScale = std::min(0.49f, std::max(edgeScale, 0.0f));
@ -196,7 +223,7 @@ std::vector<std::vector<cv::Point>> CImageOutHole::filterPoly(std::vector<std::v
if (m[i][2] != -1) continue;
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
if (rrect.size.width > 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<std::vector<cv::Point>> CImageOutHole::filterPoly(std::vector<std::v
return hole_contours;
}
cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vector<cv::Point> pixelPoints)
cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints)
{
if (pixelPoints.empty()) return cv::Scalar(255, 255, 255);
@ -239,3 +266,58 @@ cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vec
temp[1] / static_cast<int>(pixelPoints.size()),
temp[2] / static_cast<int>(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<float>(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;
}

View File

@ -1,18 +1,39 @@
/*
* ====================================================
*
*
* 2020/11/21
* 2020/05/12 v1.0
* 2020/11/17 v1.1
* 2021/09/06 v1.2 50100
* 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<cv::Mat>& mats, bool isTwoSide);
@ -35,11 +56,15 @@ 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<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i> &m, cv::RotatedRect roi,
std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m, cv::RotatedRect roi,
float edgeScale, float areaThreshold);
cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> 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;
@ -47,3 +72,4 @@ private:
};
#endif // !IMAGE_APPLY_OUT_HOLE_H

View File

@ -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;
}

BIN
huagao/auge_logo.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
huagao/auge_logo1111.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
huagao/hanvon.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
huagao/hanvon_log.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View File

@ -16,6 +16,7 @@
#include "Device/PublicFunc.h"
#include "Device/GScanO200.h"
#include "Device/GScanO400.h"
#include "Device/GScanO400Android.h"
#include "Device/GScanO1003399.h"
#include "Device/filetools.h"
#include "Device/GScanVirtual.h"
@ -59,6 +60,7 @@ enum class CapTypeEx : unsigned short {
TwEx_LowPowerMode = 0x8104,
TwEx_ENCODE = 0x8105,
TwEx_CropModel=0x8106,
TwEx_DogEarDistance = 0x8107,
};
enum class PaperSizeEx : unsigned short {
@ -92,6 +94,8 @@ static constexpr const Identity srcIdent(
"HUAGO",
#elif defined HANVON
"HANVON",
#elif defined AUGE
"AUGE",
#elif defined LANXUM
"LANXUM",
#else // MAKEHUAGAO
@ -120,7 +124,7 @@ static constexpr const Identity srcIdent(
#elif defined HANVON
"HW-7000W Series",
#else // ISG100
"G300 Series",
"G200 Series",//兼容旧极课 pm changed G300 Series
#endif
#elif defined(G400) // G200
@ -138,6 +142,8 @@ static constexpr const Identity srcIdent(
#ifdef ISG100
#ifdef MAKEHUAGAO
"HUAGOSCAN G100 TWAIN"
#elif defined AUGE
"AUGESCAN G100 TWAIN"
#elif defined LANXUM //!LANXUM
"LANXUMSCAN G62S TWAIN"
#else // !MAKEHUAGAO
@ -159,7 +165,7 @@ static constexpr const Identity srcIdent(
#ifdef UV
"HUAGOSCAN G300UV TWAIN"
#else
"HUAGOSCAN G300 TWAIN"
"HUAGOSCAN G200 TWAIN"// 兼容旧极课 pm changed "HUAGOSCAN G300 TWAIN"
#endif
#elif defined HANVON
@ -264,11 +270,14 @@ struct Vid_pid
#ifdef LANXUM
static std::vector<Vid_pid> 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<Vid_pid> DeviceID{
#endif // ISG100
};
#elif defined AUGE
static std::vector<Vid_pid> DeviceID{
{0x3072,0x0130},
};
#elif defined HANVON
static std::vector<Vid_pid> DeviceID{
{0x2903,0x7000},
};
#else
static std::vector<Vid_pid> DeviceID{
{0x64B,0x7823},
@ -295,7 +310,7 @@ static std::vector<Vid_pid> 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()) + "份文件!";
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);
}
}
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);
}
}
}
}
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<Bool>, _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<Int16>()):"");
if (msg == Msg::Set) {
auto item = data.currentItem<Int16>();
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<Compression>, _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<CapType::ICompression>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::ICompression>();
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<CapType::IBitDepth>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IBitDepth>();
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<CapType::IPixelType>()) : "");
if( Msg::Set==msg) {
auto mech = data.currentItem<CapType::IPixelType>();
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;
}
else{
m_scanparam->multi_output_red = 0;//非彩色模式下多流输出不可用
@ -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<CapType::IAutomaticColorEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticColorEnabled>();
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<CapType::IAutomaticColorNonColorPixelType>()) : "");
if (msg == Msg::Set) {
auto mech = data.currentItem<CapType::IAutomaticColorNonColorPixelType>();
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<CapType::IJpegQuality>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IJpegQuality>();
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<CapType::IXferMech>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IXferMech>();
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<CapType::IXResolution>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IXResolution>(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<UInt16>()) : "");
if (Msg::Set == msg) {
if (m_scanparam->is_autocrop)
return success();
//if (m_scanparam->is_autocrop)
// return success();
auto paper = data.currentItem<UInt16>();
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<Bool>()) : "");
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<Bool>();
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<CapType::IOrientation>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IOrientation>();
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<Fix32>()) : "");
if (Msg::Set == msg) {
auto res = data.currentItem<Fix32>();
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<Bool, Bool, CapType::FeederLoaded>(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<CapType::Indicators>()) : "");
if (Msg::Set == msg) {
auto show = data.currentItem<CapType::Indicators>();
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<CapType::FeederEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::FeederEnabled>();
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<CapType::DuplexEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::DuplexEnabled>();
bool mech = data.currentItem<CapType::DuplexEnabled>();
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<BYTE, Bool, CapType::DuplexEnabled>(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<CapType::AutoFeed>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::AutoFeed>();
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<CapType::IImageFileFormat>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IImageFileFormat>();
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<CapType::IAutomaticDeskew>()) : "");
if (Msg::Set == msg) {
auto atuodsw = data.currentItem<CapType::IAutomaticDeskew>();
m_scanparam->autodescrew = (bool)atuodsw;
@ -1350,8 +1383,11 @@ 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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if ((!m_scanparam->is_duplex) && mech == TRUE)
return badValue();
m_scanparam->is_switchfrontback = mech;
return success();
}
@ -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<CapType::IAutomaticRotate>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticRotate>();
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<CapType::AutoScan>()) : "");
if (Msg::Set == msg) {
auto autoscan = data.currentItem<CapType::AutoScan>();
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<CapType::IAutoSize>()) : "");
if (Msg::Set == msg) {
auto autosize = data.currentItem<CapType::IAutoSize>();
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<CapType::IAutomaticBorderDetection>()) : "");
if (Msg::Set == msg) {
auto autodetectborder = data.currentItem<CapType::IAutomaticBorderDetection>();
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<Int32>()) : "");
if (Msg::Set == msg) {
auto autocrop = data.currentItem<Int32>();
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<CapType::IAutoDiscardBlankPages>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutoDiscardBlankPages>();
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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<BYTE, Bool, (CapType)CapTypeEx::TwEx_IAutoDiscardBlankVince>(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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (m_scanparam->is_duplex && mech)
m_scanparam->is_backrotate180 = mech;
if (mech)
m_scanparam->is_duplex = 1;
else
return badValue();
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IBackRotate180>(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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
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<Bool>()) : "");
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<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (m_scanparam->pixtype == (BYTE)PixelType::Rgb)
m_scanparam->multi_output_red = mech;
else
m_scanparam->multi_output_red = 0;//非彩色 不能使用多流除红
return badValue();
//m_scanparam->multi_output_red = 0;//非彩色 不能使用多流除红
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IMultiOutputRed>(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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<CapType::IFilter>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IFilter>();
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<Int16>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int16>();
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<Int16>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int16>();
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<CapType::IBrightness>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IBrightness>(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<CapType::IContrast>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IContrast>(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<CapType::IGamma>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IGamma>(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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->hardwarecaps.en_stapledetect = mech;
@ -1843,9 +1903,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_StableDetectEnable>(msg, data, m_scanparam->hardwarecaps.en_stapledetect, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_StableDetectEnable>(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<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->is_dogeardetection = mech;
@ -1853,9 +1914,25 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_DogEarDelection>(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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (mech >= 10 && mech <= 300)
m_scanparam->dogeardistance = mech;
else
return badValue();
return success();
}
return CapSupGetAllResetEx<UInt32, UInt32, (CapType)CapTypeEx::TwEx_DogEarDistance>(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<UInt16>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration<UInt16>(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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
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<Bool>()) : "");
switch (msg) {
case Msg::Get:{
data = Capability::createOneValue<Bool>((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,60 +2626,31 @@ 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::duration<int, ratio<24 * 60 * 60>>>(chrono::system_clock::now().time_since_epoch()).count()){
hgmsg(_T("纸轮搓纸次数已超过设计使用范围,扫描过程中搓纸失败、歪斜、搓多张等异常频次可能会明显增多,请注意及时清洁、并联系设备供应商购买替换纸轮!"));
config.setrollermsgdata(chrono::duration_cast<chrono::duration<int, ratio<24 * 60 * 60>>>(chrono::system_clock::now().time_since_epoch()).count());
}
}
scanner->config_params(*m_scanparam);
if (m_bIndicator) {
@ -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();

View File

@ -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<Twpp::CapType, std::function<Twpp::Result(Twpp::Msg msg, Twpp::Capability& data)>> 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

Binary file not shown.

Binary file not shown.

Binary file not shown.