当前位置:首页>办公设备>扫描仪>

扫描仪怎么更改导入设置(扫描仪的数据怎么添加)

扫描仪怎么更改导入设置(扫描仪的数据怎么添加)

更新时间:2022-02-18 21:27:17

大部分扫描仪都支持TWAIN协议,为了方便开发扫描仪应用程序,TWAIN组织在GitHub上放了虚拟扫描仪的示例代码。这份代码只支持加载自带的TWAIN图标,ADF连续扫描也不起作用。为了更真实的模拟扫描不同的图片,我们可以对源码做些修改。

文档扫描流程

修改代码之前,我们可以先了解下扫描文档的流程。虚拟扫描仪就是在source这层。

开发测试环境

开发

  • Visual Studio 2017及以上(官方提供了比较早的工程)
  • Qt 5.12.11 msvc2017或者Qt 5.12.11 msvc2017_64。这里取决于你要编译32位还是64位的程序

测试

  • 在线测试程序:Dynamic Web TWAIN online demo (http://demo.dynamsoft.com/web-twain/)
  • 本地测试程序:twacker (http://github.com/twain/twain-toolkit/tree/master/releases)
编译及调试编译工程

获取源码:

git clone http://github.com/twain/twain-samples.git

设置系统变量QTDIR:

在系统PATH中添加:C:Qt5.12.11msvc2017_64in。注意,如果你还添加了arm或者mingw,一定要保证msvc在最前面,不然通过windeployqt部署的时候,拿到的DLL是错误的。

用管理员权限启动Visual Studio。导入工程之后编译。编译好会生成TWAINDS_Sample32.ds或者TWAINDS_Sample64.ds动态链接库,对应的输出路径分别是C:Windows wain_32sample2或者C:Windows wain_64sample2。

现在用测试工具打开,应该可以看到扫描仪。点击扫描仪可以加载默认的图片。

调试程序

运行twacker。

在Visual Studio中挂载进程:

挂载之后,执行扫描就会跳到断点。

通过调试程序,我们可以了解源码的工作流程。接下来修改代码。

虚拟扫描仪加载自定义图片

通过调试发现,每次点击扫描,DLL都会被重新加载,所有的变量都会重置。要在内存中保留图片索引不行。解决方法是写一个配置文件。这里有另外一个问题就是windows目录下默认没有写权限,只有读权限。所以创建两个文件source.json,info.json,一个放在windows目录下指定自定义图片的目录,一个放在图片目录中包含图片索引信息和一次最大扫描量(用于ADF)。

source.json:

{ "folder": "C:/Users/admin/Pictures/barcode" }

info.json

{ "index": 0, "maxcount": 10 }

在CScanner_FreeImage.cpp的resetScanner()函数中,我们读取自定义的配置文件。通过索引设置一张当前图片,然后更新索引,写回到配置文件中,用于下一次的扫描:

char szTWAIN_DS_DIR[PATH_MAX]; GetModuleFileName(g_hinstance, szTWAIN_DS_DIR, PATH_MAX); // strip filename from path size_t x = strlen(szTWAIN_DS_DIR); while (x > 0) { if (PATH_SEPERATOR == szTWAIN_DS_DIR[x - 1]) { szTWAIN_DS_DIR[x - 1] = 0; break; } --x; } char sourceConfig[PATH_MAX]; SSNPRINTF(sourceConfig, sizeof(sourceConfig), PATH_MAX, "%s%csource.json", szTWAIN_DS_DIR, PATH_SEPERATOR); if (FILE_EXISTS(sourceConfig)) { // Read the image folder from source.json ifstream stream(sourceConfig); json source; stream >> source; stream.close(); string imageFolder = source["folder"]; if (FILE_EXISTS(imageFolder.c_str())) { // Get the image index and max image count for ADF string infoPath = imageFolder PATH_SEPERATOR "info.json"; ifstream infoStream(infoPath); json info; infoStream >> info; infoStream.close(); int index = info["index"]; m_nDocCount = m_nMaxDocCount = info["maxcount"]; WIN32_FIND_DATAA data; HANDLE handle = FindFirstFileA((imageFolder "\*").c_str(), &data); if (handle == INVALID_HANDLE_VALUE) throw std::runtime_error("Invalid handle value! Please check your path..."); while (FindNextFileA(handle, &data) != 0) { string filename = std::string(data.cFileName); string path = imageFolder PATH_SEPERATOR filename; string suffix = path.substr(path.length() - 4, 4); if (!suffix.compare(".jpg") || !suffix.compare(".png")) { images.push_back(path); } } FindClose(handle); if (images.size() > 0) { if (index >= images.size()) index = 0; // Set a custom image memset(m_szSourceImagePath, 0, PATH_MAX); SSNPRINTF(m_szSourceImagePath, sizeof(m_szSourceImagePath), PATH_MAX, images[index].c_str()); // Save image index to info.json index = 1; info["index"] = index; std::ofstream stream(infoPath); stream << info << std::endl; stream.close(); } } }

现在如果一张张扫描,已经可以正常工作了,不过ADF模式还不起作用。我们在acquireImage()函数中,针对ADF加入下面的代码:

if (images.size() > 0 && m_nPaperSource == SFI_PAPERSOURCE_ADF) { memset(m_szSourceImagePath, 0, PATH_MAX); SSNPRINTF(m_szSourceImagePath, sizeof(m_szSourceImagePath), PATH_MAX, images[m_nDocCount - 1].c_str()); }

现在可以重新编译这个虚拟扫描仪,然后通过在线程序测试:

修改之前

修改之后

源码

http://github.com/yushulx/windows-virtual-scanner

,