.NET TWAIN 图像扫描仪
使用 TWAIN API 扫描图像
摘要
在 Windows 图像应用程序中,最常用的扫描 API 是 TWAIN www.twain.org。不幸的是,新的 .NET Framework 没有内置的 TWAIN 支持。因此,我们必须使用 .NET 的互操作方法来访问此 API。本文不解释这些互操作技术,并且假定您对 TWAIN 1.9 规范有很好的了解!包含的示例代码不提供一个完整的库,而只是一个将 TWAIN 适配到 .NET 应用程序的一些基本步骤。
详细信息
第一步是将 TWAIN.H 的最重要的部分移植过来,这些部分可以在 TwainDefs.cs 中找到。调用 TWAIN 的实际逻辑在文件 TwainLib.cs 中的 Twain
类中编码。由于 TWAIN API 由 Windows DLL twain_32.dll 暴露,因此我们必须使用 .NET DllImport
机制进行与旧代码的互操作。该 DLL 导出了一个名为 DSM_Entry()
,序号为 #1 的核心函数,作为 TWAIN 的入口点。此调用有许多参数,最后一个参数的类型是可变的! 发现最好声明多个调用的变体,例如
[DllImport("twain_32.dll", EntryPoint="#1")]
private static extern TwRC DSMparent(
[In, Out] TwIdentity origin,
IntPtr zeroptr,
TwDG dg, TwDAT dat, TwMSG msg,
ref IntPtr refptr );
Twain
类具有一个简单的 5 步接口
class Twain
{
Init();
Select();
Acquire();
PassMessage();
TransferPictures();
}
对于某种类型的“回调”,TWAIN 使用特殊的 Windows 消息,这些消息必须从应用程序消息循环中捕获。在 .NET 中,找到的唯一方法是 IMessageFilter.PreFilterMessage()
,并且此过滤器必须通过类似于 Application.AddMessageFilter()
的调用来激活。在过滤器方法中,我们必须将每个消息转发到 Twain.PassMessage()
,并获得一个提示 (enum TwainCommand
) 以指示我们如何反应。
示例应用程序
该示例是一个 Windows Forms MDI 样式的应用程序。它具有两个 TWAIN 相关的菜单项:选择源... 和 获取... 一旦图像被扫描,我们就可以将其保存到 GDI+ 支持的任何文件格式的文件中(BMP、GIF、TIFF、JPEG...)。
限制
所有代码仅在 Windows 2000SP2 上使用 Epson Perfection USB 扫描仪和 Olympus 数码相机进行测试。扫描的图像(根据 TWAIN 规范)是一个 Windows DIB,并且示例代码对错误返回代码和位图格式的检查非常少。不幸的是,.NET 中没有直接的方法可以将 DIB 转换为托管 Bitmap 类... 颜色调色板和菜单可能会出现一些已知问题。
请注意,TWAIN 的根源在于 16 位 Windows!对于在 Windows ME/XP 上支持的更现代的 API,请参阅 Windows 图像采集 (WIA)。