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. Python 刷题笔记

    Python 刷题笔记 本文记录了我在使用python刷题的时候遇到的知识点. 目录 Python 刷题笔记 选择.填空题 基本输入输出 sys.stdin 与input 运行脚本时传入参数 Pyth ...

  2. VSCode---REST Client接口测试辅助工具

    我们一般都会用 PostMan 来完成接口测试的工作,因为用起来十分简单快捷,但是一直以来我也在寻找更好的方案,一个不用切换窗口多开一个 app 的方案 -- 终于在使用 VSCode 一段时版本间, ...

  3. Centos7路由设置

    再添加路由时,很多时候都是采用命令行用route添加的.但是在机器重启后.就失效了.这里也是参考了几位博主的经验 作出以下记载 一:路由表常用设置 1.route命令路由表常用设置: //添加到主机的 ...

  4. ASP.NET Core 3.1使用Swagger

    一.什么是Swagger 随着技术的不断方法,现在的网站开发基本都是使用前后端分离的模式,这样使前端开发者和后端开发者只需要专注自己擅长的即可.但这种方式会存在一种问题:前后端通过API接口的方式进行 ...

  5. JS中Generator的学习小记

    Generator的异步实现 整理了一下在学习和使用JS异步过程中的一些知识点.核心是在Generator实例的的回调中调度实例的下一步,同样的思想也能用于其它语言.比如Python中使用Genera ...

  6. (三)文件的链接(ln)

    一.链接的分类及特点 当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在 其它的目录下用ln命令链接(link ...

  7. 为什么会有kafka消息系统?小问题藏着大细节!

    前言:老刘今天写这篇文章首先想对一些复制粘贴的博客表达不满:其次是想用通俗易懂的话解释消息系统:最后欢迎各位英雄好汉.女中豪杰前来battle. 1. 为什么有消息系统? 1.1 背景 今天复习kaf ...

  8. Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)

    前言: 上一篇文章我们讲了如何在创建的Angular项目中快速引入ng-zorro-antd企业中台组件库,并且快速构建后台管理页面框架模板.这一章主要介绍的是如何在创建好的后台管理页面框架的快速生成 ...

  9. [leetcode]355. Design Twitter设计实现一个微博系统

    //先定义一个数据结构,代表一条微博,有两个内容:发布者id,微博id(代表微博内容) class TwitterData { int userId; int twitterId; public Tw ...

  10. Qt学习笔记-Qt5和Qt4在音频方面的不同-QtAV

    之前学习qt4的时候,播放音频用的是phonon播放后端插件+mplayer. 今天改用qt5了.qt5中去掉了phonon模块加了multimedia.但是依然无法播放音乐,因为没有ffmpge s ...