跳转至

TWAIN 扫描协议介绍 / TWAIN Scanning Protocol Overview

本文档介绍 TWAIN 扫描协议,对比 WIA / eSCL,并梳理 TWAIN 的架构、应用场景和版本演进。

1. TWAIN 是什么

TWAIN 是一套面向扫描仪、数码相机等图像采集设备的开放工业标准 API,1992 年由 Hewlett-Packard、Kodak、Logitech、Aldus、Caere 等公司联合推出,由 TWAIN Working Group (https://www.twain.org) 维护。

名字由来:常被戏称为 "Technology Without An Interesting Name",官方认为它取自吉卜林的诗句 "And never the twain shall meet",象征"应用与设备相遇"。

TWAIN 解决的核心问题:

  • 让一个图像采集应用(Photoshop、XnView、Office、PDF 软件等)能与各种品牌、型号、接口的扫描仪 / 相机通信,而无需各自写设备驱动。
  • 为厂商提供统一的 SDK 入口:硬件厂商写一个符合 TWAIN 的 Data Source (DS) 即可被所有 TWAIN 应用使用。

TWAIN 不是底层硬件协议(不像 USB / SCSI),它是应用层 API,运行在操作系统之上,下面再通过厂商 DS 调用真正的设备驱动。

2. 与 WIA / eSCL 的比较

2.1 三种协议简介

协议 全称 维护方 平台 传输
TWAIN TWAIN Protocol TWAIN Working Group Windows / macOS / Linux 进程内 DLL (DS) + DSM 调度
WIA Windows Image Acquisition Microsoft Windows 专属 COM 接口 + 内核 stillimg.sys
eSCL (Mopria / Apple) AirScan / eSCL Mopria Alliance / Apple OS 无关 HTTP + XML over IPP-style URL

2.2 设计哲学对比

维度 TWAIN WIA eSCL
通信形态 同进程 DLL 加载 (DS_Entry) 进程外 COM + 内核驱动 网络 HTTP/REST + XML
用户界面 DS 自带 UI 弹窗(可选) 系统统一向导(应用可定制) 应用自带,没有"驱动 UI"
控制粒度 极细:上百个 Capability 中等:限定属性集 中等偏粗:纸张 / 颜色 / DPI 等
厂商负担 重:写完整 DS DLL 中:实现 WIA 驱动接口 轻:在固件实现 HTTP 端点
应用负担 中:状态机 + DSM 调用 中:COM 方法调用 轻:标准 HTTP GET/POST
跨平台 ✅ Windows + macOS(Linux 部分) ❌ 仅 Windows ✅ 任何能 HTTP 的平台
网络扫描 需 TWAIN Direct 扩展 通过 WSD 间接支持 原生
32/64 位互操作 历史痛点,需 32/64 位 DS 并存 无问题(驱动级) 与位宽无关
Vendor UI 体验 体验差异大、可定制 统一 Windows 风格 应用决定
高级能力 强(barcode、patch、ICC) 中(持续扩展中)

2.3 取舍场景

  • 需要细粒度控制扫描参数(双面、ADF、纸张大小、亮度、阈值、压缩选项)、面对专业 / 商用扫描仪 → TWAIN
  • 只在 Windows 上、轻量场景(Outlook 插入图片、Microsoft Office 扫描到文档)→ WIA 更省事。
  • 现代 / 移动 / 跨平台、扫描仪在网络上(家用打印一体机、办公多功能机)→ eSCL 已是事实标准(iOS、Android、macOS 默认走它)。
  • 多协议混合(同一应用支持桌面老扫描仪 + 网络多功能机)→ 应用层封一层,TWAIN + eSCL 并存。

2.4 互补关系

  • TWAIN Working Group 推出 TWAIN Direct(基于 HTTP/JSON),目的就是把 TWAIN 的语义搬到网络上,与 eSCL 在网络扫描领域形成竞争。
  • WIA 在 Windows 7+ 通过 WSD 间接支持网络扫描,但接口陈旧、UX 一般。
  • 商用文档扫描仪厂商(Fujitsu、Kodak、Canon DR、Brother、Epson WorkForce)几乎全部提供 TWAIN DS,许多还另带 WIA、ISIS、eSCL 通道。
  • 家用 / 办公多功能机(HP、Brother、Canon、Epson)逐步以 eSCL 为主,TWAIN/WIA 走 USB 时仍提供。

3. TWAIN 架构

3.1 三层架构

┌──────────────────────────────┐
│       Application (TWAIN     │   Photoshop, XnView, NAPS2,
│         compliant app)       │   Acrobat, Office, custom EXE
└──────────────┬───────────────┘
               │ DSM_Entry()  (TW_IDENTITY app, TW_IDENTITY ds,
               │                DG, DAT, MSG, pData)
┌──────────────▼───────────────┐
│   Data Source Manager (DSM)  │   TWAINDSM.dll  (TWAIN 2.x)
│                              │   TWAIN_32.dll  (TWAIN 1.x, 32-bit)
└──────────────┬───────────────┘
               │ DS_Entry()   (same signature, ds DLL exports it)
┌──────────────▼───────────────┐
│      Data Source (DS, .ds)   │   Per-device DLL written by vendor.
│      Talks to actual driver  │   Encapsulates USB/network specifics.
└──────────────────────────────┘
  • Application:发起扫描请求、显示扫描结果。引用 DSM 的导入库,调 DSM_Entry
  • Data Source Manager (DSM):操作系统级单例 DLL。负责发现、加载、卸载 DS;维护应用与 DS 的会话。
  • Data Source (DS):每个设备一个,文件后缀 .ds(实际是 DLL)。导出 DS_Entry,由 DSM 调用。

3.2 DSM 与 DS 的接口

只暴露一个函数签名:

TW_UINT16 DSM_Entry(pTW_IDENTITY origin,
                    pTW_IDENTITY dest,
                    TW_UINT32   DG,
                    TW_UINT16   DAT,
                    TW_UINT16   MSG,
                    TW_MEMREF   pData);

DG / DAT / MSG 三元组定义所有操作:

  • DG(Data Group):CONTROL / IMAGE / AUDIO 等大类。
  • DAT(Data Argument Type):参数类型,比如 DAT_IDENTITYDAT_CAPABILITYDAT_IMAGEINFODAT_IMAGENATIVEXFERDAT_IMAGEFILEXFER
  • MSG:动作,比如 MSG_OPENDSMSG_ENABLEDSMSG_GETMSG_SETMSG_RESETMSG_PROCESSEVENT

例如打开设备:

DSM_Entry(app_id, NULL,        DG_CONTROL, DAT_IDENTITY,    MSG_OPENDSM, &dsm_window);
DSM_Entry(app_id, NULL,        DG_CONTROL, DAT_IDENTITY,    MSG_GETDEFAULT, &ds_id);
DSM_Entry(app_id, &ds_id,      DG_CONTROL, DAT_IDENTITY,    MSG_OPENDS,  &ds_id);
DSM_Entry(app_id, &ds_id,      DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &ui);

3.3 状态机(7 个状态)

TWAIN 协议显式定义 7 个状态,所有合法操作必须按状态推进:

状态 名称 含义
1 Pre-Session 应用还没调用任何 TWAIN API
2 Source Manager Loaded 已加载 DSM DLL(旧式手动 LoadLibrary)
3 Source Manager Open DSM 已 OPENDSM
4 Source Open DS 已 OPENDS,可读写 capabilities
5 Source Enabled DS 已 ENABLEDS,UI 可见(如启用),等待用户 / 自动按下 Scan
6 Transfer Ready DS 已通知应用有一帧待取 (MSG_XFERREADY)
7 Transferring 应用正在传输该帧

状态推进示意:

1 → 2 LoadDSM → 3 MSG_OPENDSM → 4 MSG_OPENDS → 5 MSG_ENABLEDS
                                                  │
                                                  ▼ (DS posts MSG_XFERREADY)
                                                  6 Transfer Ready
                                                  │ DAT_IMAGEINFO
                                                  │ DAT_IMAGENATIVEXFER / DAT_IMAGEFILEXFER
                                                  ▼
                                                  7 Transferring
                                                  │ DAT_PENDINGXFERS (count, end)
                                                  ▼
                                                  5 (next image) or
                                                  4 (DisableDS)
                                                  → 3 (CloseDS) → 2 (CloseDSM) → 1

3.4 Capability 协商

TWAIN 用一组 Capability 描述设备能力,常见前缀:

  • CAP_*:通用能力(如 CAP_FEEDERENABLEDCAP_UICONTROLLABLECAP_XFERCOUNT)。
  • ICAP_*:图像能力(如 ICAP_PIXELTYPEICAP_XRESOLUTIONICAP_UNITSICAP_IMAGEFILEFORMATICAP_XFERMECH)。
  • ACAP_*:音频能力。

每个能力以 4 种 Container 表达:

  • TWON_ONEVALUE:单值。
  • TWON_ENUMERATION:枚举集合 + 默认值 + 当前值。
  • TWON_RANGE:min/max/step/默认/当前。
  • TWON_ARRAY:数组(如 CAP_SUPPORTEDCAPS 列出所有支持能力)。

每个能力支持以下操作(视实现而定):MSG_GET / GETCURRENT / GETDEFAULT / SET / RESET / QUERYSUPPORT

3.5 数据传输三种机制

ICAP_XFERMECH 选择应用如何取像素:

  • Native Transfer (TWSX_NATIVE):DS 返回 DIB / 内存图像,通过 DSM 共享内存交付。最常用、跨语言绑定友好。
  • File Transfer (TWSX_FILE):DS 直接把图像保存到应用指定路径,应用读文件。适合自动化、PDF 生成。
  • Memory Transfer (TWSX_MEMORY):分块(strip / tile)通过内存缓冲区交付,应用控制每次取走的字节数。适合超大图像。

3.6 事件循环(Windows)

Windows TWAIN 应用必须把消息循环里收到的 MSG 转发给 DS:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
  TW_EVENT te = { &msg, MSG_NULL };
  DSM_Entry(app_id, &ds_id, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &te);
  if (te.TWMessage == MSG_XFERREADY) {
    // Begin transfer.
  } else if (te.TWMessage == MSG_CLOSEDSREQ) {
    // User closed the DS UI.
  } else if (te.TWMessage == MSG_NULL) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}

DS 用 PostMessage 把异步通知(MSG_XFERREADY / MSG_CLOSEDSREQ / MSG_DEVICEEVENT)塞回应用消息队列,由应用回流给 DS。

3.7 32 位 / 64 位

历史上 TWAIN DS 只支持 32 位(TWAIN_32.dll + C:\Windows\twain_32),所以 64 位应用要么内嵌 32 位 broker 进程,要么不支持 TWAIN。TWAIN 2.x 引入 64 位 DSM (TWAINDSM.dll) 和 C:\Windows\twain_64\。本项目同时编译 32 位 / 64 位 DS 解决兼容(见 README "Dual architecture")。

4. 应用场景

  • 办公文档管理:PDF/A 归档、票据扫描、合同电子化(Adobe Acrobat、ABBYY、Foxit、Kofax、NAPS2)。
  • 专业影像 / 印刷:高分辨率胶片 / 反射稿扫描(Silverfast、VueScan、Photoshop)。
  • 医疗影像:胶片数字化、病理切片预扫(PACS 前端)。
  • 金融票据:支票扫描(Fujitsu fi 系列、Canon DR 系列、Kodak i 系列广泛使用 TWAIN DS)。
  • OCR / RPA:OCR 软件(OmniPage、Tesseract 前端)、RPA 平台(UiPath / Blue Prism)批量扫描入库。
  • 行业应用:律所证据扫描、政府档案数字化、医院病历归档。
  • 测试 / 开发:本项目 BN Tech Virtual Scanner 就是为了在没有真扫描仪的开发机上提供一个完整 TWAIN DS,便于扫描应用、PDF 软件、RPA 自动化的回归测试。

5. 版本演进

5.1 TWAIN 1.x(1992–2005)

  • 1992:TWAIN 1.0,首个公开标准。
  • 1997:TWAIN 1.7,加入更多 Capability、Mac 支持。
  • 仅 32 位(Win32 / Mac OS Classic / macOS PowerPC)。
  • DSM 二进制:TWAIN_32.dll
  • 字符串使用 8-bit ASCII(TW_STR32 等)。
  • 状态机已经成型,但能力数量、文件格式较少。

5.2 TWAIN 2.x(2008–至今)

  • 2008:TWAIN 2.0,引入新 DSM TWAINDSM.dll(独立项目,开源 LGPL)。
  • 64-bit 原生支持,统一跨平台 DSM。
  • Unicode 字符串可选(TWTY_UNI512 等)。
  • 引入新 Capability:ICAP_AUTODISCARDBLANKPAGESICAP_AUTOMATICDESKEWICAP_BARCODEDETECTIONENABLED 等。
  • 增加 ICC profile、JPEG2000、PDF/A 等文件格式。
  • 2015:TWAIN 2.3,加入 metric 单位 / 强化 ADF capabilities。
  • 2017:TWAIN 2.4,bugfix + 兼容 macOS sandbox。
  • 2022:TWAIN 2.5,本项目目标版本;进一步规范 capability 协商、增强 Native / File transfer 描述。

5.3 TWAIN Direct(2017+)

  • 不是替代 TWAIN 2.x,而是把 TWAIN 语义搬到网络上。
  • 协议:HTTPS + JSON,类似 REST。
  • 设备通过 mDNS 发布服务。
  • 与 eSCL 在网络扫描领域竞争;目前 eSCL 生态更强。
  • 应用形态:浏览器、移动 App 都能用,无需安装 DS。

5.4 版本对比

维度 TWAIN 1.x TWAIN 2.x TWAIN Direct
推出年份 1992 起 2008 起 2017 起
DSM TWAIN_32.dll TWAINDSM.dll (含 32/64) 设备内嵌 HTTPS server
位宽 仅 32-bit 32-bit + 64-bit 与位宽无关
字符串 ASCII ASCII + 可选 Unicode UTF-8 (JSON)
传输 进程内 DLL 进程内 DLL 网络 HTTPS / JSON
Vendor UI DS 自带 DS 自带或应用 应用
跨平台 Win + Mac Classic Win + macOS + Linux 部分 任意 HTTP 平台
网络扫描 不直接支持 不直接支持 原生
设备发现 DSM 扫目录 DSM 扫目录 mDNS / Bonjour
主要部署 老办公场景 当前主流商用 推广中

6. 小结

  • TWAIN 是历史最悠久、覆盖商用扫描仪最全的扫描标准,能力协商极度细致。
  • WIA 是 Windows 局限的轻量替代,适合简单场景但功能受限。
  • eSCL 是网络 / 跨平台扫描的事实新标准,正在挤占家用 / 办公多功能机的接口位。
  • 本项目实现的是 TWAIN 2.5 兼容的虚拟 Data Source,用于在没有真实硬件的情况下完整模拟 TWAIN 协议链路;详细模块设计见同目录其他设计文档(docs/native_transfer_design.mddocs/file_transfer_design.mddocs/pixel_type_design.md 等)。