mirror of http://192.168.1.51:8099/lmh188/twain3.0
调整twain协议
This commit is contained in:
parent
a74735c8d8
commit
e7c4c666f6
|
@ -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.更新穿孔算法
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: 在此添加控件通知处理程序代码
|
||||
}
|
||||
|
|
@ -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();
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -55,4 +55,5 @@ private:
|
|||
public:
|
||||
afx_msg void OnCbnSelchangeCblowpowermode();
|
||||
afx_msg void OnNMReleasedcaptureSliderdpi(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnBnClickedBtnAttribyte();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
|
@ -246,6 +246,7 @@ void GScanO1003399::config_params(GScanCap& param)
|
|||
}
|
||||
cfg.g200params.dpi = SupResolutions.count(param.resolution_native)>0 ? SupResolutions[param.resolution_native] : 1;
|
||||
cfg.g200params.double_feed_enbale = (unsigned int)param.hardwarecaps.en_doublefeed;
|
||||
//cfg.g200params.stable_enbale = 0;
|
||||
cfg.g200params.stable_enbale = (unsigned int)param.hardwarecaps.en_stapledetect;
|
||||
cfg.g200params.screw_detect_enable = (unsigned int)param.hardwarecaps.en_skrewdetect;
|
||||
cfg.g200params.screw_detect_level = (unsigned int)cfg.g200params.screw_detect_enable ? secrewMaps[param.hardwarecaps.skrewdetectlevel] : 0;
|
||||
|
@ -313,6 +314,7 @@ void GScanO1003399::config_params(GScanCap& param)
|
|||
param39.papertype = param.papertype;
|
||||
param39.pixtype = param.pixtype;
|
||||
param39.resolution_dst = param.resolution_dst;
|
||||
//param39.resolution_dst = param.resolution_dst > 300 ? 300 : param.resolution_dst;
|
||||
param39.resolution_native = param.resolution_native;
|
||||
param39.scannum = param.scannum;
|
||||
param39.sharpen = param.sharpen;
|
||||
|
@ -320,7 +322,25 @@ void GScanO1003399::config_params(GScanCap& param)
|
|||
param39.multiOutput = MultiOutput::Unused;
|
||||
param39.normalCrop = param.normalCrop;
|
||||
m_usb->write_bulk(¶m39, sizeof(param39));
|
||||
|
||||
if (param.is_autotext)
|
||||
{
|
||||
TCHAR szIniFile[MAX_PATH] = { 0 };
|
||||
SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE);
|
||||
#ifdef LANXUM
|
||||
_tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata"));
|
||||
#elif defined AUGE
|
||||
_tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\tessdata"));
|
||||
#elif defined HANVON
|
||||
_tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\tessdata"));
|
||||
#else
|
||||
_tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata"));
|
||||
#endif //
|
||||
int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL);
|
||||
char* chRtn = new char[iLen * sizeof(char)];
|
||||
WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL);
|
||||
m_autotext.reset(new CImageApplyRotation(CImageApplyRotation::RotationType::AutoTextOrientation, false, param.resolution_dst, chRtn));
|
||||
delete[] chRtn;
|
||||
}
|
||||
}
|
||||
|
||||
void GScanO1003399::Scanner_StartScan(UINT16 count)
|
||||
|
@ -427,7 +447,7 @@ void GScanO1003399::Stop_scan()
|
|||
|
||||
int GScanO1003399::notifyscan()
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GScanO1003399::ResetScanner()
|
||||
|
@ -693,7 +713,6 @@ int GScanO1003399::read_data(void* data, int length, int timeout)
|
|||
int reading = 0;
|
||||
const int buffer_size = 512 * 1024;
|
||||
StopWatch sw;
|
||||
FileTools::writelog(log_INFO, "read_data timeout =" + to_string(timeout));
|
||||
while (readed < length) {
|
||||
if (sw.elapsed_ms() < timeout &&m_usb.get())
|
||||
{
|
||||
|
@ -762,32 +781,7 @@ void GScanO1003399::imgproce(std::shared_ptr<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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -446,7 +446,7 @@ void GScanO200::Scanner_StartScan(UINT16 count)
|
|||
|
||||
int GScanO200::notifyscan()
|
||||
{
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GScanO200::Stop_scan()
|
||||
|
|
|
@ -187,10 +187,6 @@ void GScanO400::open(int vid, int pid)
|
|||
USBCB status = { GET_DSP_STATUS ,0,0 };
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
{
|
||||
//m_usb->write_bulk(&status, sizeof(status));
|
||||
//m_usb->read_bulk(&status, sizeof(status));
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
//notifyscan();
|
||||
GetFWVersion();
|
||||
}
|
||||
}
|
||||
|
@ -264,10 +260,6 @@ std::string GScanO400::GetFWVersion()
|
|||
m_usb->read_bulk(&fwVersion[0], fwVersion.size());
|
||||
std::this_thread::sleep_for(chrono::milliseconds(10));
|
||||
}
|
||||
if (fwVersion.substr(0, 2) == "G3" || fwVersion.substr(0, 2) == "G4" ||fwVersion.substr(0,2)== "GU")
|
||||
is_Android = false;
|
||||
else
|
||||
is_Android = true;
|
||||
return fwVersion;
|
||||
}
|
||||
return "";
|
||||
|
@ -431,7 +423,6 @@ void GScanO400::Scanner_StartScan(UINT16 count)
|
|||
devState = DEV_WRONG;
|
||||
int errorcode = 0;
|
||||
readlenght == 0 ? errorcode = USB_DISCONNECTED : errorcode = NO_FEED;
|
||||
|
||||
Set_ErrorCode(errorcode);
|
||||
if (huagods)
|
||||
dev_callback(errorcode, huagods);
|
||||
|
@ -617,8 +608,6 @@ void GScanO400::usbmain()
|
|||
this_thread::sleep_for(chrono::milliseconds(200));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (sw.elapsed_ms() > 30000)
|
||||
{
|
||||
m_pImages->setscanflags(false);
|
||||
|
@ -667,9 +656,7 @@ void GScanO400::usbmain()
|
|||
#else
|
||||
UpdateScanInfo(countNReaded(), get_imgTransfered());
|
||||
#endif
|
||||
|
||||
if (!is_Android)
|
||||
Pop_Image();
|
||||
Pop_Image();
|
||||
FileTools::writelog(log_INFO, "从扫描仪接收" + to_string(get_imgnReaded()) + "份文件。耗时 " + to_string(sw.elapsed_ms()));
|
||||
sw.reset();
|
||||
break;
|
||||
|
@ -677,7 +664,7 @@ void GScanO400::usbmain()
|
|||
case STOP_SCAN:
|
||||
{
|
||||
m_pImages->setscanflags(false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
|
||||
break;
|
||||
}
|
||||
|
@ -695,25 +682,11 @@ void GScanO400::usbmain()
|
|||
case USB_BULK_ERROR:
|
||||
if (!haveError)
|
||||
{
|
||||
//if (is_Android)
|
||||
//{
|
||||
haveError = true;
|
||||
Set_ErrorCode(usbcb.u32_Data);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// haveError = true;
|
||||
// devState = DEV_WRONG;
|
||||
// m_pImages->setscanflags(false);
|
||||
// Set_ErrorCode(usbcb.u32_Data);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
// auto rollernew = Get_Roller_num();
|
||||
// if (get_aquire_image_count() != (rollernew - roller_num))
|
||||
// set_lose_image_num(std::abs((rollernew - roller_num) - get_aquire_image_count()));
|
||||
//}
|
||||
|
||||
if (huagods)
|
||||
dev_callback(usbcb.u32_Data, huagods);
|
||||
|
||||
}
|
||||
break;
|
||||
case NORMAL:
|
||||
|
@ -726,12 +699,8 @@ void GScanO400::usbmain()
|
|||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
//writelog(e.what());
|
||||
FileTools::writelog(log_ERROR, e.what());
|
||||
}
|
||||
|
||||
////FileTools::write_log("D:\\1.txt", "thread usb exit");
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -745,18 +714,6 @@ USBCB GScanO400::Get_Scanner_Status()
|
|||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||||
if (usbcb.u32_CMD != GET_DSP_STATUS)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50));
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
m_usb->read_bulk(&usbcb, 512);
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
m_usb->read_bulk(&usbcb, 512);
|
||||
FileTools::writelog(log_ERROR, "get dsp status error");
|
||||
return { NO_COMMAND,USB_BULK_ERROR,0 };
|
||||
}
|
||||
return usbcb;
|
||||
}
|
||||
|
||||
|
@ -768,26 +725,6 @@ std::shared_ptr<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 };
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "GScan.h"
|
||||
#include <memory>
|
||||
|
||||
#include "StopWatch.h"
|
||||
|
||||
class GScanO400 : public IScanner
|
||||
{
|
||||
|
|
|
@ -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(¬ify, sizeof(notify));
|
||||
//m_usb->read_bulk(¬ify, sizeof(notify));
|
||||
//if ((notify.u32_Data != 0x10 && GetFWVersion().length() < 10) || notify.u32_Data == 0x100)
|
||||
//{
|
||||
// ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("扫描仪处于休眠状态,请按电源键唤醒! 提示 "), NULL, SW_HIDE);
|
||||
// return -1;
|
||||
//}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void GScanO400Android::Stop_scan()
|
||||
{
|
||||
std::lock_guard<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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) });
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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字节做协议扩展*/
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
|
@ -3,7 +3,7 @@
|
|||
#include <Windows.h>
|
||||
#include <usbscan.h>
|
||||
#endif // WINDOWS
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include "IUsb.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <log4cplus/log4cplus.h>
|
||||
#include "PublicFunc.h"
|
||||
|
||||
#define enum2str(R) #R
|
||||
|
||||
enum log_lv :int {
|
||||
log_TRACE = 0,
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
float pos[] = { 0, 2 * fact, fact };
|
||||
const float fact = 0.33f;
|
||||
float pos[] = { 0, 2 * fact, fact };
|
||||
cv::Point2f dstTri[3];
|
||||
dstTri[0] = cv::Point2f(1, 1);
|
||||
dstTri[1] = cv::Point2f(1, 0.5);
|
||||
dstTri[2] = cv::Point2f(0, 1);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
dstTri[0] = cv::Point2f(1, 1 + pos[i]);
|
||||
|
@ -123,8 +117,15 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
|||
if (m_noise > 0)
|
||||
{
|
||||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise, 1));
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element);
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
}
|
||||
|
||||
if (m_indent > 0)
|
||||
{
|
||||
cv::Mat element = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(m_indent, m_indent));
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_ERODE, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
}
|
||||
|
||||
std::vector<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;
|
||||
|
|
|
@ -5,13 +5,24 @@
|
|||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21 v1.0
|
||||
2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用)
|
||||
2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度。
|
||||
2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG。
|
||||
2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG。
|
||||
2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏)
|
||||
2020/11/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底。
|
||||
* 版本号:v1.3.0
|
||||
2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用)
|
||||
2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度。
|
||||
2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG。
|
||||
2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG。
|
||||
2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏)
|
||||
2020/11/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底。
|
||||
2021/06/18 v1.3.1 调整默认noise为8。
|
||||
2021/07/01 v1.3.2 修复 无裁切情况下,自适应颜色除黑底不生效的BUG。
|
||||
2021/07/08 v1.3.3 完善流程。当无法定位内容时,且为固定幅面裁切,则返回按照固定幅面进行裁切的结果。
|
||||
2021/07/08 v1.3.4 调整参数,让消除背景噪声不对纵向像素造成影响。
|
||||
2021/07/09 v1.3.5 增加normalCrop机制,当m_isCrop m_isDesaskew m_isFillBlank均为false时可选用,实现传统裁切。
|
||||
2021/07/13 v1.3.6 调整normalCrop逻辑,当normalCrop为true时,m_isCrop m_isDesaskew m_isFillBlank失效。
|
||||
2021/07/19 v1.3.7 调整仿射变换模式为INTER_LINEAR。
|
||||
2021/07/22 v1.3.8 修复第二次寻边,找不到外界轮廓会导致崩溃的BUG。
|
||||
2021/08/02 v1.3.9 精细化除黑底算法,可以应对只有条纹内容的黑色图像。
|
||||
2021/10/08 v1.3.10 优化算法,用腐蚀代替绘制实现缩进,提高整体算法效率。
|
||||
2021/10/19 v1.3.11 解决一些极端情况,例如纸张自然0角度,纸张定格在图像顶部的处理。
|
||||
* 版本号:v1.3.11
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -58,7 +69,7 @@ public:
|
|||
|
||||
double threshold() { return m_threshold; }
|
||||
|
||||
const cv::RotatedRect& rotatedROI() { return m_rect; }
|
||||
cv::RotatedRect& rotatedROI() { return m_rect; }
|
||||
|
||||
const std::vector<cv::RotatedRect>& rotatedROIs() { return m_rects; }
|
||||
|
||||
|
|
|
@ -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;//邻域尺寸
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
#include "ImageProcess_Public.h"
|
||||
|
||||
CImageApplyDogEarDetection::CImageApplyDogEarDetection()
|
||||
: m_threshold(40)
|
||||
, m_zoom(1.0)
|
||||
, m_distance(50)
|
||||
, m_result(false)
|
||||
: m_threshold(40)
|
||||
, m_zoom(1.0)
|
||||
, m_distance(50)
|
||||
, m_result(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CImageApplyDogEarDetection::CImageApplyDogEarDetection(double threshlod, double zoom, double distance)
|
||||
: m_threshold(threshlod)
|
||||
, m_zoom(zoom)
|
||||
, m_distance(distance)
|
||||
, m_result(false)
|
||||
: m_threshold(threshlod)
|
||||
, m_zoom(zoom)
|
||||
, m_distance(distance)
|
||||
, m_result(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -24,44 +24,49 @@ CImageApplyDogEarDetection::~CImageApplyDogEarDetection()
|
|||
|
||||
}
|
||||
|
||||
void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side)
|
||||
void CImageApplyDogEarDetection::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
m_result = false;
|
||||
(void)side;
|
||||
if (pDib.empty()) return;
|
||||
cv::Mat src;
|
||||
if (m_zoom != 1.0)
|
||||
cv::resize(pDib, src, cv::Size(), m_zoom, m_zoom, cv::INTER_NEAREST);
|
||||
else
|
||||
src = pDib;
|
||||
m_result = false;
|
||||
(void)side;
|
||||
if (pDib.empty()) return;
|
||||
cv::Mat src;
|
||||
if (m_zoom != 1.0)
|
||||
cv::resize(pDib, src, cv::Size(), m_zoom, m_zoom, cv::INTER_NEAREST);
|
||||
else
|
||||
src = pDib;
|
||||
|
||||
cv::Mat thre;
|
||||
hg::threshold_Mat(src, thre, m_threshold);
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||
cv::Mat thre;
|
||||
hg::threshold_Mat(src, thre, m_threshold);
|
||||
|
||||
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
|
||||
if (maxContour.size() == 0)
|
||||
{
|
||||
m_result = true;
|
||||
return;
|
||||
}
|
||||
hg::convexHull(maxContour, maxContour);
|
||||
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
||||
cv::Point2f vertexes[4];
|
||||
rect.points(vertexes);
|
||||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(20, 1));
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if ((-cv::pointPolygonTest(maxContour, vertexes[i], true)) > (m_distance * m_zoom))
|
||||
{
|
||||
m_result = true;
|
||||
return;
|
||||
}
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||
|
||||
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
|
||||
if (maxContour.size() == 0)
|
||||
{
|
||||
m_result = true;
|
||||
return;
|
||||
}
|
||||
hg::convexHull(maxContour, maxContour);
|
||||
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
||||
cv::Point2f vertexes[4];
|
||||
rect.points(vertexes);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if ((-cv::pointPolygonTest(maxContour, vertexes[i], true)) > (m_distance * m_zoom))
|
||||
{
|
||||
m_result = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyDogEarDetection::apply(std::vector<cv::Mat> &mats, bool isTwoSide)
|
||||
void CImageApplyDogEarDetection::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
(void)mats;
|
||||
(void)isTwoSide;
|
||||
(void)mats;
|
||||
(void)isTwoSide;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#include "ImageApplyOutHole.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
|
||||
CImageOutHole::CImageOutHole(void)
|
||||
#ifdef LOG
|
||||
#include "Device/filetools.h"
|
||||
#endif // LOG
|
||||
|
||||
CImageApplyOutHole::CImageApplyOutHole(void)
|
||||
: CImageApply()
|
||||
, m_borderSize(200)
|
||||
, m_borderSize(600)
|
||||
, m_edgeScale(0.1f)
|
||||
, m_threshold(50)
|
||||
, m_threshold(100)
|
||||
{
|
||||
}
|
||||
|
||||
CImageOutHole::CImageOutHole(float borderSize, float edgeScale, double threshold)
|
||||
CImageApplyOutHole::CImageApplyOutHole(float borderSize, float edgeScale, double threshold)
|
||||
: CImageApply()
|
||||
, m_borderSize(borderSize)
|
||||
, m_edgeScale(edgeScale)
|
||||
|
@ -17,26 +21,35 @@ CImageOutHole::CImageOutHole(float borderSize, float edgeScale, double threshold
|
|||
{
|
||||
}
|
||||
|
||||
CImageOutHole::~CImageOutHole(void)
|
||||
CImageApplyOutHole::~CImageApplyOutHole(void)
|
||||
{
|
||||
}
|
||||
|
||||
void CImageOutHole::apply(cv::Mat& pDib, int side)
|
||||
void CImageApplyOutHole::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
(void)pDib;
|
||||
(void)side;
|
||||
(void)pDib;
|
||||
(void)side;
|
||||
}
|
||||
|
||||
void CImageOutHole::apply(std::vector<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);
|
||||
|
||||
|
@ -235,7 +262,62 @@ cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vec
|
|||
temp[j] += ptr[j];
|
||||
}
|
||||
|
||||
return cv::Scalar(temp[0] / static_cast<int>(pixelPoints.size()),
|
||||
temp[1] / static_cast<int>(pixelPoints.size()),
|
||||
temp[2] / static_cast<int>(pixelPoints.size()));
|
||||
return cv::Scalar(temp[0] / static_cast<int>(pixelPoints.size()),
|
||||
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;
|
||||
}
|
|
@ -1,18 +1,39 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:装订孔填充
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/11/21
|
||||
* 最近修改时间:2020/05/12 v1.0
|
||||
* 2020/11/17 v1.1
|
||||
* 2021/09/06 v1.2 调整默认二值化阈值,从原来的50调整为100。将填充颜色从局部颜色提取改为全局颜色提取。
|
||||
* 2021/11/03 v1.3 增加逻辑,如果正反面图像尺寸差异超过10个像素,直接返回,不再进行除穿孔处理。
|
||||
* 2021/11/04 v1.4 增加背景抗噪机制,能够抗5像素的背景噪声。
|
||||
* 2021/11/17 v1.5 调整代码格式,避免一些由于opencv版本导致的BUG。
|
||||
* 版本号:v1.5
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_APPLY_OUT_HOLE_H
|
||||
#define IMAGE_APPLY_OUT_HOLE_H
|
||||
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageOutHole : public CImageApply
|
||||
class CImageApplyOutHole : public CImageApply
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CImageOutHole();
|
||||
CImageApplyOutHole();
|
||||
|
||||
CImageOutHole(float borderSize, float edgeScale, double threshold);
|
||||
/*
|
||||
* borderSize [in]:孔洞面积阈值
|
||||
* edgeScale [in]:纸张边缘区域比例,取值范围(0,0.5),默认值0.1
|
||||
* threshold [in]:二值化阈值
|
||||
*/
|
||||
CImageApplyOutHole(float borderSize, float edgeScale, double threshold);
|
||||
|
||||
~CImageOutHole(void);
|
||||
~CImageApplyOutHole(void);
|
||||
|
||||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
|
@ -26,7 +47,7 @@ public:
|
|||
|
||||
void setEdgeScale(float scale) { m_edgeScale = scale; }
|
||||
|
||||
void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); }
|
||||
void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -35,15 +56,20 @@ private:
|
|||
void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front,
|
||||
cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect);
|
||||
|
||||
std::vector<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;
|
||||
double m_threshold;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_OUT_HOLE_H
|
||||
#endif // !IMAGE_APPLY_OUT_HOLE_H
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 158 KiB |
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
After Width: | Height: | Size: 129 KiB |
|
@ -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()) + "份文件!";
|
||||
scanner->set_lose_image_num(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (((num - scanner->get_imgTransfered()) != 0) || ((readnum - scanner->get_imgnReaded()) != 0)) {
|
||||
text += "进纸" + to_string(scanner->get_scannum()) +
|
||||
",扫描" + to_string(scanner->get_imgnReaded()) + ",上传" + to_string(scanner->get_imgTransfered()) +
|
||||
",扫描相差" + to_string(readnum - scanner->get_imgnReaded()) + "份文件,上传相差" + to_string(num - scanner->get_imgTransfered()) + "份文件!";
|
||||
scanner->set_lose_image_num(0);
|
||||
}
|
||||
}
|
||||
|
||||
text += "\n扫描统计信息:\n进纸(张)" + to_string(scanner->get_scannum()) +
|
||||
"\n扫描(张)" + to_string(imgread) + "\n扫描相差(张)" + to_string(scanner->get_scannum() - imgread) +
|
||||
"\n上传(页)" + to_string(scanner->get_imgTransfered()) + "\n上传相差(页)" + to_string(num - scanner->get_imgTransfered());
|
||||
scanner->set_lose_image_num(0);
|
||||
}
|
||||
}
|
||||
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString((text + " " + caption).c_str()), NULL, SW_HIDE);
|
||||
}
|
||||
|
||||
void HuagaoDs::hgmsg(CString str)
|
||||
{
|
||||
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
|
||||
}
|
||||
HuagaoDs::~HuagaoDs()
|
||||
{
|
||||
if (memoryinfo.get()) {
|
||||
|
@ -803,26 +806,24 @@ void HuagaoDs::dogear_callback(int indexpaper)
|
|||
CString text;
|
||||
text.Format(_T("74 %d"), indexpaper);
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
|
||||
showmsg("警告","在"+to_string(indexpaper)+"检测到折角!");
|
||||
showmsg("提示","在"+to_string(indexpaper)+"检测到折角!");
|
||||
scanner->Stop_scan();
|
||||
//scanner->reset();
|
||||
scanner->ResetScanner();
|
||||
onDeviceEvent(DOG_EAR);
|
||||
}
|
||||
|
||||
|
||||
Result HuagaoDs::identityOpenDs(const Identity&) {
|
||||
|
||||
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp"));
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) { //如果已经存在同名的Mutex会得到这个错误.
|
||||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("202"), NULL, SW_HIDE);
|
||||
showmsg("警告", msgs[(UsbSupported)202]);
|
||||
showmsg("提示", msgs[(UsbSupported)202]);
|
||||
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
|
||||
}
|
||||
|
||||
|
||||
|
||||
Twain_config().GetOrSetPintfCapability(is_printfcapability, true);
|
||||
auto usblist = UsbScan_List::find_all_usb();
|
||||
if (!usblist.empty())
|
||||
{
|
||||
|
@ -836,12 +837,16 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
pid = usb.pid;
|
||||
if (!scanner.get()) {
|
||||
#ifdef G200
|
||||
if (pid == 0x139 || pid == 0x239)
|
||||
if (pid == 0x139 || pid == 0x239 || pid == 0x8739 || pid == 0x8629)
|
||||
scanner.reset(new GScanO1003399());
|
||||
else
|
||||
scanner.reset(new GScanO200());
|
||||
#else
|
||||
#ifdef ANDROIDSERIAL
|
||||
scanner.reset(new GScanO400Android());
|
||||
#else
|
||||
scanner.reset(new GScanO400());
|
||||
#endif
|
||||
#endif // G400
|
||||
break;
|
||||
}
|
||||
|
@ -854,8 +859,8 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
if (vid == 0 || pid == 0)
|
||||
{
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
|
||||
//showmsg("警告", msgs[(UsbSupported)201]);
|
||||
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("未找到扫描仪!请检查电源或者USB连接线是否接通! 警告"), NULL, SW_HIDE);
|
||||
//showmsg("提示", msgs[(UsbSupported)201]);
|
||||
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("未找到扫描仪!请检查电源或者USB连接线是否接通! 提示"), NULL, SW_HIDE);
|
||||
if (hMutex) {
|
||||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
|
@ -869,12 +874,12 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
}
|
||||
showmsg("警告", msgs[(UsbSupported)81]);
|
||||
showmsg("提示", msgs[(UsbSupported)81]);
|
||||
return seqError();
|
||||
}
|
||||
if (!scanner->IsConnected()) {
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
|
||||
showmsg("警告", msgs[(UsbSupported)201]);
|
||||
showmsg("提示", msgs[(UsbSupported)201]);
|
||||
if (hMutex) {
|
||||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
|
@ -887,7 +892,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
auto dgcall = [&](int pagenum)
|
||||
{
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
|
||||
showmsg("警告", "在" + to_string(pagenum) + "检测到折角!");
|
||||
showmsg("提示", "在" + to_string(pagenum) + "检测到折角!");
|
||||
scanner->Stop_scan();
|
||||
//scanner->reset();
|
||||
scanner->ResetScanner();
|
||||
|
@ -931,6 +936,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
m_query[CapType::DeviceOnline] = msgSupportGetAll;
|
||||
//m_caps[CapType::DeviceOnline] = std::bind(enmGet<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;
|
||||
m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None;
|
||||
}
|
||||
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,10 +1383,13 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
|
||||
m_query[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = msgSupportGetAllSetReset;
|
||||
m_caps[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = [this](Msg msg, Capability& data)->Result {
|
||||
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_SwitchFrontBack), msg == Msg::Set ? to_string((int)data.currentItem<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();
|
||||
return success();
|
||||
}
|
||||
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_SwitchFrontBack>(msg, data, m_scanparam->is_switchfrontback, false);
|
||||
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_SwitchFrontBack>(msg, data, { FALSE,TRUE }, m_scanparam->is_switchfrontback, (Bool)false, m_scanparam->is_switchfrontback ? 1 : 0, 0);
|
||||
|
@ -1361,6 +1397,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
|
||||
m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset;
|
||||
m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result {
|
||||
CapabilityPrintf(msg, enum2str(CapType::IAutomaticRotate), msg == Msg::Set ? to_string((int)data.currentItem<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>();
|
||||
m_scanparam->is_backrotate180 = mech;
|
||||
if (mech)
|
||||
m_scanparam->is_duplex = 1;
|
||||
if (m_scanparam->is_duplex && mech)
|
||||
m_scanparam->is_backrotate180 = mech;
|
||||
else
|
||||
return badValue();
|
||||
return success();
|
||||
}
|
||||
return CapSupGetAllResetEx<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,59 +2626,30 @@ Twpp::Result HuagaoDs::startScan()
|
|||
|
||||
scanner->ResetScanner();
|
||||
scanner->reset();
|
||||
//std::string info = "开始扫描 ===> 扫描配置参数为:\n\t m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop);
|
||||
//info += "\n\t m_scanparam->colorenable :" + to_string(m_scanparam->automaticcolor);
|
||||
//info += "\n\t m_scanparam->colorenabletype :" + to_string(m_scanparam->automaticcolortype);
|
||||
//info += "\n\t m_scanparam->papertype :" + to_string(m_scanparam->papertype);
|
||||
//info += "\n\t m_scanparam->fillbackground :" + to_string(m_scanparam->fillbackground);
|
||||
//info += "\n\t m_scanparam->autodescrew :" + to_string(m_scanparam->autodescrew);
|
||||
//info += "\n\t m_scanparam->brightness :" + to_string(m_scanparam->brightness);
|
||||
//info += "\n\t m_scanparam->Caption :" + m_scanparam->Caption;
|
||||
//info += "\n\t m_scanparam->contrast :" + to_string(m_scanparam->contrast);
|
||||
//info += "\n\t m_scanparam->discardblank_percent :" + to_string(m_scanparam->discardblank_percent);
|
||||
//info += "\n\t m_scanparam->enhance_color :" + to_string(m_scanparam->enhance_color);
|
||||
//info += "\n\t m_scanparam->en_fold :" + to_string(m_scanparam->en_fold);
|
||||
//info += "\n\t m_scanparam->hardwarecaps.capturepixtype :" + to_string(m_scanparam->hardwarecaps.capturepixtype);
|
||||
//info += "\n\t m_scanparam->hardwarecaps.en_doublefeed :" + to_string(m_scanparam->hardwarecaps.en_doublefeed);
|
||||
//info += "\n\t m_scanparam->hardwarecaps.en_stapledetect :" + to_string(m_scanparam->hardwarecaps.en_stapledetect);
|
||||
//info += "\n\t m_scanparam->hardwarecaps.en_skrewdetect :" + to_string(m_scanparam->hardwarecaps.en_skrewdetect);
|
||||
//info += "\n\t m_scanparam->hardwarecaps.skrewdetectlevel :" + to_string(m_scanparam->hardwarecaps.skrewdetectlevel);
|
||||
//info += "\n\t m_scanparam->imageRotateDegree :" + to_string(m_scanparam->imageRotateDegree);
|
||||
//info += "\n\t m_scanparam->is_duplex :" + to_string(m_scanparam->is_duplex);
|
||||
//info += "\n\t m_scanparam->pixtype :" + to_string(m_scanparam->pixtype);
|
||||
//info += "\n\t m_scanparam->resolution_dst :" + to_string(m_scanparam->resolution_dst);
|
||||
//info += "\n\t m_scanparam->resolution_native :" + to_string(m_scanparam->resolution_native);
|
||||
//info += "\n\t m_scanparam->paperAlign :" + to_string((int)m_scanparam->paperAlign);
|
||||
//info += "\n\t m_scanparam->gamma :" + to_string(m_scanparam->gamma);
|
||||
//info += "\n\t m_scanparam->threshold :" + to_string(m_scanparam->threshold);
|
||||
//info += "\n\t m_scanparam->is_autocontrast :" + to_string(m_scanparam->is_autocontrast);
|
||||
//info += "\n\t m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop);
|
||||
//info += "\n\t m_scanparam->fillhole.fillholeratio :" + to_string(m_scanparam->fillhole.fillholeratio);
|
||||
//info += "\n\t m_scanparam->fillhole.is_fillhole :" + to_string(m_scanparam->fillhole.is_fillhole);
|
||||
//info += "\n\t m_scanparam->is_autodiscradblank_normal :" + to_string(m_scanparam->is_autodiscradblank_normal);
|
||||
//info += "\n\t m_scanparam->is_autodiscradblank_vince :" + to_string(m_scanparam->is_autodiscradblank_vince);
|
||||
//info += "\n\t m_scanparam->is_switchfrontback :" + to_string(m_scanparam->is_switchfrontback);
|
||||
//info += "\n\t m_scanparam->multi_output_red :" + to_string(m_scanparam->multi_output_red);
|
||||
//info += "\n\t m_scanparam->hsvcorrect :" + to_string(m_scanparam->hsvcorrect);
|
||||
//info += "\n\t m_scanparam->filter :" + to_string(m_scanparam->filter);
|
||||
//info += "\n\t m_scanparam->sharpen :" + to_string(m_scanparam->sharpen);
|
||||
//info += "\n\t m_scanparam->scannum :" + to_string(m_scanparam->scannum);
|
||||
//info += "\n\t m_scanparam->is_backrotate180 :" + to_string(m_scanparam->is_backrotate180);
|
||||
//info += "\n\t m_scanparam->is_autotext :" + to_string(m_scanparam->is_autotext);
|
||||
//info += "\n\t m_scanparam->SavePath :" + m_scanparam->SavePath;
|
||||
//info += "\n\t m_scanparam->noise :" + to_string(m_scanparam->noise);
|
||||
//info += "\n\t m_scanparam->indent :" + to_string(m_scanparam->indent);
|
||||
//info += "\n\t m_scanparam->AutoCrop_threshold :" + to_string(m_scanparam->AutoCrop_threshold);
|
||||
//info += "\n\t m_scanparam->is_convex :" + to_string(m_scanparam->is_convex);
|
||||
//FileTools::write_log("D:\\1.txt",info);
|
||||
FileTools::writelog(log_INFO, "start scan");
|
||||
#ifndef G200
|
||||
if(scanner->notifyscan()<1)
|
||||
#ifdef G200
|
||||
#ifndef ANDROIDSERIAL
|
||||
if (scanner->notifyscan() < 1)
|
||||
return seqError();
|
||||
|
||||
#endif // !ANDROIDSERIAL
|
||||
scanner->clear_hwerror();
|
||||
#endif //
|
||||
|
||||
#ifdef G200
|
||||
if (scanner->Get_Roller_num() > 450000)
|
||||
#elif defined G300
|
||||
if (scanner->Get_Roller_num() > 150000)
|
||||
#else
|
||||
if (scanner->Get_Roller_num() > 200000)
|
||||
#endif // G200
|
||||
{
|
||||
Twain_config config;
|
||||
if (config.getrollermsgdate() < chrono::duration_cast<chrono::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());
|
||||
}
|
||||
}
|
||||
|
||||
#endif //
|
||||
|
||||
scanner->config_params(*m_scanparam);
|
||||
|
||||
|
@ -2618,11 +2695,11 @@ Twpp::Result HuagaoDs::startScan()
|
|||
//ShellExecute(guiTwain ? guiTwain->m_hWnd : NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
|
||||
int index = scanner->geterrorindex();
|
||||
if (retCode == 82)
|
||||
showmsg("警告", "在第" + to_string(index) + "页检测到折角,停止扫描!", retCode);
|
||||
showmsg("提示", "在第" + to_string(index) + "页检测到折角,停止扫描!", retCode);
|
||||
else if (retCode == 75)
|
||||
showmsg("警告", "在第" + to_string(index) + "页检测到尺寸不符,停止扫描!", retCode);
|
||||
showmsg("提示", "在第" + to_string(index) + "页检测到尺寸不符,停止扫描!", retCode);
|
||||
else
|
||||
showmsg("警告", msgs[(UsbSupported)retCode], retCode);
|
||||
showmsg("提示", msgs[(UsbSupported)retCode], retCode);
|
||||
FileTools::writelog(log_ERROR, msgs[(UsbSupported)retCode]);
|
||||
#ifndef G200
|
||||
scanner->clear_hwerror();
|
||||
|
|
|
@ -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.
BIN
huagao/stdafx.h
BIN
huagao/stdafx.h
Binary file not shown.
Loading…
Reference in New Issue