C#:使用Twain协议实现扫描仪连续扫描
如果用Twain协议实现一次扫描多张图片?相信有接触过Twain协议与扫描仪通信的朋友都遇到过这样的问题。按照网上的例子,在连续送纸的扫描仪中,调用一次却只能扫描一张图片,怎么破?
关于这个问题 我研究了好久,终于在困扰了我7天之后,我搞定了,下面分享一下我的解决经验。
新建一个ScanCommon类,在调用界面,写下调用扫描的方法:
ScanCommon scan = new RS_ScanCommon(fileName, this.Handle);
scan.PassDataBetweenForm += new RS_ScanCommon.PassDataBetweenFormHandler(scan_PassDataBetweenForm); //是否连续扫描
scan.bContinuousScan = true;
scan.dtRow = dtRow;
this.Enabled = false;
scan.StartScan();
在ScanCommon类中,调用Twain的接口类(Twain类网络上可以找到,本文略),主要代码如下:
// 添加一个委托
public delegate void PassDataBetweenFormHandler(object sender, PassDataEventArgs e);
// 添加一个PassDataBetweenFormHandler 类型的事件
public event PassDataBetweenFormHandler PassDataBetweenForm; public ScanCommon(string fileName, IntPtr Handle)
{
this.fileName = fileName;
this.Handle = Handle; //扫描初始化(默认使用TWAIN方式进行连接)
tw = new Twain();
tw.Init(Handle, out rc);
//tw.Select();
} //启动扫描
public void StartScan()
{
if (rc != TwRC.Success)
{
MessageBox.Show("设备初始化失败,请检查硬件及驱动!");
}
else
{
string path = "XXX路径" + "\\ScannerFile\\" + frmName;
if (Scanning(path) == false)
{
MessageBox.Show("设备未找到或设备不支持TWAIN组件,无法自动创建扫描任务。") ; //回调主窗口
PassDataEventArgs args = new PassDataEventArgs("exit");
PassDataBetweenForm(this, args);
GC.Collect();
}
}
}
在ScanCommon类中,主要的扫描方法均可以通过调用twain类实现,Scanning是调用驱动实现扫描的方法。Application.AddMessageFilter是添加扫描仪的事件监听,在监听事件中返回扫描仪的不同状态以实现取消和扫描的一些操作。
主要代码如下:
#region 扫描的一些方法
private bool Scanning(string filePath)
{
if (!msgfilter)
{
msgfilter = true;
Application.AddMessageFilter(this);
}
ScanPath = filePath;
return tw.Acquire(ref strScanErrorMessage, bContinuousScan);
} /// <summary>
/// 保存图片
/// </summary>
/// <param name="dibhandp"></param>
private void ImageSave(IntPtr dibhandp)
{
bmprect = new Rectangle(0, 0, 0, 0);
if (dibhandp != IntPtr.Zero) dibhand = dibhandp;
bmpptr = GlobalLock(dibhand);
pixptr = GetPixelInfo(bmpptr);
} public void EndingScan()
{
if (msgfilter)
{
tw.Finish();
RemoveMessageFilter(this);
msgfilter = false;
}
} public static void RemoveMessageFilter(IMessageFilter value)
{
Application.RemoveMessageFilter(value);
}
#endregion
在监听的TwainCommand.TransferReady状态中,是调用扫描仪扫描图片的。我开始的时候尝试修改twain类中TransferPictures的方法,但是结果证实不可行。
其实这是一个误区,我们只需要修改一下twain的启动扫描事件,可以根据是否连续扫描给扫描仪传不同的参数以达到此效果。
只需一行代码,就可实现一次扫描多张,且不需要更改扫描仪的任何设置。
如果设备支持连续送纸,启动扫描时扫描仪会直接连扫直到纸张全部扫完
//此行代码是连续扫描
TwCapability cap = new TwCapability(TwCap.XferCount, -1);
代码如下:
/// <summary>
/// 启动扫描
/// </summary>
/// <param name="strScanErrorMessage"></param>
/// <returns></returns>
public bool Acquire(ref string strScanErrorMessage, bool MultiScan)
{
try
{
TwRC rc;
CloseSrc();
if (appid.Id == IntPtr.Zero)
{
Init(hwnd, out rc);
if (appid.Id == IntPtr.Zero)
strScanErrorMessage = "未找到扫描仪设备,请查看是否安装扫描仪驱动!";
return false;
}
rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.OpenDS, srcds);
if (rc != TwRC.Success)
{
strScanErrorMessage = "未找到扫描仪设备";
return false;
} if (MultiScan)
{
//如果是连续扫描
TwCapability cap = new TwCapability(TwCap.XferCount, -1);
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);
}
else
{
//否则只扫描一张
TwCapability cap = new TwCapability(TwCap.XferCount, 1);
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);
} if (rc != TwRC.Success)
{
strScanErrorMessage = "未找到扫描仪设备";
CloseSrc();
return false;
} TwUserInterface guif = new TwUserInterface();
guif.ShowUI = 1;
guif.ModalUI = 1;
guif.ParentHand = hwnd;
rc = DSuserif(appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, guif);
if (rc != TwRC.Success)
{
strScanErrorMessage = "扫描仪中没有纸";
CloseSrc();
GC.Collect();
return false;
}
}
catch (Exception e)
{
strScanErrorMessage = e.Message;
GC.Collect();
return false;
}
GC.Collect();
return true;
}
扫描结束后,回调主窗口返回数据,主窗口添加如下事件:
private void scan_PassDataBetweenForm(object sender, PassDataEventArgs e)
{
if (e.EventStr == "exit")
{
this.Cursor = Cursors.WaitCursor;
frm.dtRow = this.dtRow; //处理图片的一些方法.... this.Enabled = true;
this.Cursor = Cursors.Default;
GC.Collect();
}
}
特别声明:本文由Healer007原创,署名小萝卜。转载请注明出处。谢谢!
C#:使用Twain协议实现扫描仪连续扫描的更多相关文章
- C# Twain协议调用扫描仪,设置多图像输出模式(Multi image output)
Twain 随着扫描仪.数码相机和其他图像采集设备的引入,用户热切地发现了将图像整合到他们的文档和其他工作中的价值.然而,支持这种光栅数据的显示和操作成本很高,应用程序开发人员需要创建用户界面并内置设 ...
- Twain协议部分翻译
转载:https://blog.csdn.net/a848691591/article/details/41006807 4.1 性能 应用程序与源进行性能协商的能力使人们能够控制TWAIN兼容的程序 ...
- java Twain 直接打印/界面打印
这两天,在搞归档系统.需要用到Twain协议来驱动扫描仪. 找了两天,java的twain操作资料真的不多.而且我还是要找直接打印的功能. 后来只能静下心来看类库和源码.最后搞定他. 打印方式分为3种 ...
- Python常用模块之VideoCapture
官方网址:http://videocapture.sourceforge.net/ 功能介绍: VideoCapture是Win32版Python的一个扩展,可以访问视频采集设备(如USB摄像头) ...
- 扫描仪API接入大全:Twain, WIA 或 两者不具有.[换个思路 春暖花开]
最近做和扫描仪接入的扫描应用程序,深深感觉到了来自底层设备和WINDOWS协议的恶意.软件专业,对计算机深层次通知机制和协议,以及与之相连接的机器的接入协议和一些参数,当时并木有认真学习和了解,前一阵 ...
- Pywinauto在Windows Twain Driver自动化测试中的应用研究
摘 要: 以Python为基础,结合对Twain Driver测试工具的具体需求,将Pywinauto引入到Twain Driver的自动化测试中.介绍了Pywinauto的基本概念,通过测试用例说 ...
- 扫描控件Web在线Applet
基于JAVAEE的B/S架构由于java语言的跨平台性 所以操控Window客户端资源能力有限, 目前比较流行是用其他语言如Delphi,VB,C++开发客户端控件 然后再html中用js调用. ...
- TWAIN-v2.4-说明文档翻译(1)介绍
介绍 Introduction 一致性需求(Need for Consistency) 对于扫描仪,数字摄像仪,以及其他图像获取设备,用户渴望发现将图像合并到他们的文档以及其他工作的价值.然而,支持展 ...
- 主机-配件-接口-整机-3c-1
standby 待机 hibernate 休眠(睡眠) power-off 关机 usb端口能给外部设备充电在低压状态(standby,hibernate,power-off),如果系统运行在batt ...
随机推荐
- Debian系统vim中文显示乱码问题
网上查的一堆东西好像都不灵,试了半天! 先安装中文字体:sudo aptitude install fonts-arphic-uming fonts-wqy-zenhei 然后:sudo locale ...
- SqlServer自动化分区
1.新增文件组 ALTER DATABASE [Test] ADD FILEGROUP FG2010 ALTER DATABASE [Test] ADD FILEGROUP FG2011 ALTER ...
- linux c++循环缓冲区模板类
一:概述 实际学习和工作中,我们经常会遇到读写大量数据的情况,这个时候我们可能就用到了循环缓冲区. 循环缓冲区在处理大量数据的时候有很大的优点,循环缓冲区在一些竞争问题上提供了一种免锁的机制,免锁的前 ...
- WWDC2016的一点个人想法
看了游戏审核的新闻和WWDC,感觉个人游戏开发者会很难混下去了,WWDC里面iMessage 透露出来的信息,我感觉微信有竞争者了,假如苹果把iMessage 打造成微信那种模式(聊天+第三方接入), ...
- Android 下进行单元测试 Test run failed:Instrumentation run failed due to 'java.lang.ClassNotFoundException'
废话不说,一直报错.网上介绍的都是缺少如下声明之类. 但注意的是工程配置是导出junit包, 路径为 project上右键 --> properties -> java build pa ...
- Windows XP和Word 2007不能正常使用VSTO插件
今天帮助同事解决了一个小问题,就是在WindowsXP上,为Word2007开发的插件不能正常显示. 通过搜索关键词 WindowsXp Word 2007 VSTO找到了两个解决方案. http:/ ...
- 《《我是一只IT小小鸟》》读后感
接触IT也已经半年了,在这半年我没有充足的时间去了解IT这个行业,在大学生职业规划课程上,老师推荐了<<我是一只IT小小鸟>>这本书,我才发现IT这个行业并不是想象的那么无趣, ...
- Java程序性能优化技巧
Java程序性能优化技巧 多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for ...
- CentOS7 bonding配置
操作系统:CentOS Linux release 7.1.1503 (Core) 网卡适配器: eno1.eno2 bonding类型:mode=1 (active-backup),主-备份策略 网 ...
- myrocks 之数据字典
data dictionary rocksdb作为mysql的一个新的存储引擎,在存储引擎层,会维护自已的元数据信息.在innodb存储引擎中,我们通过information_schema下的INNO ...