Twain

随着扫描仪、数码相机和其他图像采集设备的引入,用户热切地发现了将图像整合到他们的文档和其他工作中的价值。然而,支持这种光栅数据的显示和操作成本很高,应用程序开发人员需要创建用户界面并内置设备控制各种各样可用的图像设备。

一旦他们的应用程序准备好支持给定的设备,他们就会面临一个令人沮丧的现实:设备不断地升级新的功能和特性。应用程序开发人员发现他们不断地修改他们的产品,以保持最新图像采集设备和软件应用程序的开发人员都认识到需要图像设备和应用程序之间的标准通信。一个标准有利于使用他们产品的用。它将允许更多的应用程序访问设备供应商的产品,而应用程序供应商可以访问来自这些设备的数据,而不需要关心提供这些数据的是哪种类型的设备或特定的设备。

TWAIN的开发正是出于对一致性和简化的需要。

Twain 开发简介

TWAIN定义了一个标准的软件协议和API(应用程序编程接口),用于在软件应用程序和图像采集设备(数据的来源)之间进行通信。

Twain的三个关键要素是:

  • Application software

    必须修改应用程序才能使用TWAIN。
  • Source Manager software

    该软件管理应用程序和源程序之间的交互。这段代码在TWAIN开发者的工具包中提供,每个TWAIN应用程序和源代码都应该免费提供。
  • Source software

    该软件控制图像采集设备,由设备开发人员按照TWAIN规范编写。传统的设备驱动程序现在包含在源软件中,不需要由应用程序提供。

关于这几要素是什么关系呢?通俗的说就是Twain是一个协议,这个协议不需要我们自己去实现和设备(我这里是扫描仪)的通讯,这个通讯是由一个叫做Data Source Manager的来提供,我们的应用程序只需要调用Data Source Manager对应的功能,然后由Data Source Manager去负责和支持Twain协议的设备通讯(准确的说应该是设备的驱动)。

这个Data Source Manager 在windows里面就是由twain_32.dll实现。

Twain协议PDF https://ask.qcloudimg.com/draft/7651952/jhzuki5dnp.pdf

Twain通讯过程

TWAIN元素之间的通信可以通过两个入口点实现。他们是DSM_Entry()和DS_Entry()。DSM指数据源管理器(也就是twain_32.dll),DS指数据源(驱动程序)。

应用程序的目标是从源获取数据。但是应用程序不能直接调用源。所有对数据、功能信息、错误信息等的请求都必须通过源管理器处理。

Twain定义了大约140个操作。应用程序将它们发送到源管理器进行传输。应用程序指定哪个元素(源管理器或源)是每个请求操作的最终目的地。

应用程序通过源管理器唯一的入口点DSM_Entry()函数与源管理器通信。DSM_Entry函数的参数列表包含:

  • 一个标识符结构,提供关于发起函数调用的应用程序的信息。
  • 请求的目的地(源管理器或源)。
  • 描述请求操作的三元组(triplet)。三元组指:

    操作的数据组(DG_)

    操作的数据参数类型(DAT_)

    操作的消息(MSG_)
  • 函数调用返回一个值(返回码),指示操作的成功或失败。
TW_UINT16 TW_CALLINGSTYLE DSM_Entry
( pTW_IDENTITY pOrigin, // source of message
pTW_IDENTITY pDest, // destination of message
TW_UINT32 DG, // data group ID: DG_xxxx
TW_UINT16 DAT, // data argument type: DAT_xxxx
TW_UINT16 MSG, // message ID: MSG_xxxx
TW_MEMREF pData // pointer to data
);

Twain状态

应用程序、源管理器和源必须通信来管理数据的获取。这个过程必须以特定的顺序发生,这是合乎逻辑的。例如,在加载源管理器并准备好进行请求通信之前,应用程序无法成功地请求来自源的数据传输。为了保证序列的正确执行,TWAIN协议定义了在TWAIN会话中存在的七种状态。会话是应用程序通过源管理器连接到特定源的时间段。

应用程序连接到源管理器的期间是一个唯一的会话,Source Manager和Source的TWAIN元素都占据一个特定的状态。到新状态的转换是由应用程序或源请求的操作引起的,转换可以向前或向后进行。大多数转换都是单状态转换。

转换状态图如下:

State 1 to 2 -加载source manager 获取 DSM_Entry接口

State 2 to 3 - 打开source manager

State 3 - 选择 Source

State 3 to 4 - 打开 Source

State 4 - 设置source的Capabilities

State 4 to 5 - 请求从source获取数据

State 5 to 6 - 数据可以准备消息

State 6 to 7 - 开始数据传输

State 7 to 6 to 5 - 完成传输

State 5 to 1 - 断开连接

C# 调用

应用程序调用Source Manager,使用NTwain进行操作,在nuget里面添加引用。

对应的github地址,里面有源码和demo: https://github.com/soukoku/ntwain/tree/v3

添加引用后打开source manager,然后可以选择Source 或者加载默认Source。

打开Source后状态为4 则我们可以对设备进行设置,而设置这些功能存在于许多种类中,但都有默认值、当前值和可能的值

其他可选的可支持的值。这些种类可以在协议里面查到,也就是驱动里面对应的各种设置。在Twain协议里面把这些功能叫做Capabilities ,对应的NTwain包里面也封装了,比如设置扫描仪双面扫描

_twain.CurrentSource.Capabilities.CapDuplexEnabled.SetValue(BoolType.True);

关于富士通fujitsu设置图像模式:多图像输出

这里有个大坑,在使用NTwain设置的时候通过CapPixelType设置图像模式只能设置黑白灰度彩色三种,通过如下代码:

_twain.CurrentSource.Capabilities.ICapPixelType.SetValue(PixelType.RGB)

不能设置多图输出,在驱动里面找看到图片确实只支持这几种方式,然后我一直以为是我看掉了哪个功能,看完了Twain协议,然后去网上各种找没有这方面的资料,大部分都是很简单的介绍,纠结了一周没有搞清楚。然后搜到vintasoft 这个网站的时候看到一个提问才恍然大悟,原来这个设置Twain标准协议里面确实没有这个,我估计是富士通厂家自己搞的一个。因为上面Twain通讯过程说了各种操作只能通过DSM_Entry()函数,并且只要你传入的三元组的( TW_UINT16 DAT,// data argument type: DAT_xxxx) Id正确且支持就行了。

使用如下代码new一个多图像输出功能对象,然后像其它一样设置即可。

new CapWrapper<MutilImageOutPutType>(dataSource, (CapabilityId)0x80f2, ValueExtensions.ConvertToEnum<MutilImageOutPutType>,
value => new TWOneValue
{
Item = (uint)value,
ItemType = ItemType.UInt16
});
public enum MutilImageOutPutType : ushort
{
Disabled = 0,
RGBAndBW = 1,
BWAndRGB = 2,
Enabled = 3,
Auto = 4,
}

最后扫描获取图片

C# Twain协议调用扫描仪,设置多图像输出模式(Multi image output)的更多相关文章

  1. C#:使用Twain协议实现扫描仪连续扫描

    如果用Twain协议实现一次扫描多张图片?相信有接触过Twain协议与扫描仪通信的朋友都遇到过这样的问题.按照网上的例子,在连续送纸的扫描仪中,调用一次却只能扫描一张图片,怎么破? 关于这个问题 我研 ...

  2. B/S(WEB)系统中使用Activex插件调用扫描仪实现连续扫描并上传图像(IE文件扫描并自动上传)

    IE浏览器下使用Activex插件调用客户端扫描仪扫描文件并山传,可以将纸质档案(如合同.文件.资料等)扫描并将扫描图像保存到服务器,可以用于合同管理.档案管理等. 通过插件方式调用扫描仪扫描并获取图 ...

  3. Twain协议部分翻译

    转载:https://blog.csdn.net/a848691591/article/details/41006807 4.1 性能 应用程序与源进行性能协商的能力使人们能够控制TWAIN兼容的程序 ...

  4. 教程-Delphi 调用控制面板设置功能

    应用程序运行时,有时需要对系统环境有特殊要求.例如,在Delphi数据库应用程序中可能需要进行BDE(Borland Database Engine)或ODBC数据源名称(DSN:Data Sourc ...

  5. C#如何使用Soap协议调用WebService?

    WebService是什么?它的作用? WebService是一个平台独立.低耦合的.自包含的.基于可编程的可使用xml描述.调用的web应用程序,用于开发分布式的交互式的应用程序. Soap是什么? ...

  6. 四层协议给站点设置独享ip

    四层协议给站点设置独享ip 初始化为四层节点 设置独占ip 设置独享的产品不用预设置分组 增加站点 创建站点后,在分组解析里会自动创建一个以站点名为名称的分组并且会自动分配一个独享的ip在这个分组里( ...

  7. ios --- 调用系统"设置"里的功能(转)

    安装后第一次运行软件时,系统会弹出提示用户是否允许软件获取当前位置,如果用户不允许的话,之后运行时系统不会在弹出提示设置,这点很不方便,有个解决办法是给用户一个选项,调出iphone中“设置”定位服务 ...

  8. destoon6.0调用公司设置任意信息的方法-最新

    destoon6.0调用公司设置任意信息的方法 用法: 把以下函数加入到api/extend.func.php 中 function company_setting($userid, $key = ' ...

  9. iOS 使用UI控件的外观协议UIAppearance进行设置默认UI控件样式

    在iOS开发中,经常会对UINavigationBar的样式进行全局样式.采用的设置方式有两种: 第一种,采用方式如下: [UINavigationBar appearance] 这种是对一类对象的默 ...

随机推荐

  1. javascript笔记day01

    JavaScript基础语法 HTML :标记语言 JavaScript :编程语言 序言 JavaScript发展历史(JS) 1. 1994年,网景公司(Netscape)发布了Navigator ...

  2. 自学python,从小白到大神,需要多久?

    2020年10月 TIOBE 排行榜超过了 Java, 历史上首次 Python 超越了 Java ,再次让许多朋友对 Python 产生了兴趣,今天我们来梳理下学习 Python 几个阶段或者级别, ...

  3. (四)、vim的缓冲区、标签、窗口操作

    1.缓冲区的基本操作 a.文件与缓冲区的区别 vim file1   打开一个文件时,其实是从磁盘中读取文件到内存中,文件的内容会被加载到缓冲区中, 这个缓冲区在一个窗口上显示,所以他是一个已激活的缓 ...

  4. junit 测试用例多并发

    最近再用测试用例写个多并发,但是测试用例一运行完程序就结束啦.还没有等到多线程运行完.这个时候可以用断点在多线程后面停住或者让主线程睡眠多一些

  5. IDEA git 切换分支

    如图:打开DIEA , 在右下角找到Git分支 , 然后选择你要切换的分支 , 最后选择 Checkout

  6. JavaDailyReports10_11

    ********************************** 验证码 AWT Swing 1 package nanshen; 2 3 import java.awt.Container; 4 ...

  7. JS中var与let的区别

    区别: var声明的变量,其作用域在该语句所在的函数之内,存在着变量提升的现象. let声明的变量,其作用域为该句所在的代码块内,不存在变量提升的问题. let相比于var,其不允许在相同作用域内,重 ...

  8. SalesForce学习——权限管理

    Salesforce 对于权限的管理是非常严谨的并且支持不同维度的权限控制.常用的有简档.权限集.角色层级机构.组织范围. 简档:Profiles是Salesforce为每个用户指定的标准配置文件,在 ...

  9. Spring Boot 2.x基础教程:实现文件上传

    文件上传的功能实现是我们做Web应用时候最为常见的应用场景,比如:实现头像的上传,Excel文件数据的导入等功能,都需要我们先实现文件的上传,然后再做图片的裁剪,excel数据的解析入库等后续操作. ...

  10. mysql源码分析-启动过程

    mysql源码分析-启动过程 概要 # sql/mysqld.cc, 不包含psi的初始化过程 mysqld_main: // 加载my.cnf和my.cnf.d,还有命令行参数 if (load_d ...