如何从文档进纸器异步扫描和传输图像

Posted

技术标签:

【中文标题】如何从文档进纸器异步扫描和传输图像【英文标题】:How can I scan and transfer images from a document feeder asynchronously 【发布时间】:2011-05-26 02:21:38 【问题描述】:

与 TWAIN 通信的哪些部分可以放入另一个线程,例如背景工作者? 要么: 是否可以拆分处理图像传输的循环?

一些扫描仪驱动程序在返回调用应用程序之前扫描所有图像,这会强制应用程序一次处理所有图像。这导致例如当突然必须立即处理所有事件(在每个扫描图像后引发)时,我的 WPF 应用程序中出现 OutOfMemoryException 或奇怪行为。此外,应用程序挂起,直到传输完成。

我正在使用 TwainDotNet:http://code.google.com/p/twaindotnet/,但我也在寻找一个通用的解决方案来描述消息过滤器以及与 TwainDotNet 无关的 TWAIN 的交互。包含 TWAIN 消息的工作流就足够了。也欢迎使用其他语言,最好使用 C 或 Deplhi 之类的语言。

DataSourceManager 中消息过滤器的当前实现可以描述如下:

从窗口句柄 (hwnd) 获取消息信息 复杂的过滤器,将东西发送到 TWAIN 等。 如果消息关闭(例如,当按下 TWAIN UI 中的取消按钮时) 关闭数据源 禁用过滤器 呼叫扫描完成事件 如果消息传输准备好: 在循环中(直到 ADF 为空等,这会阻塞消息过滤器) 获取图片 将图像指针转换为 GDI+ 图像 以图像为参数调用 TransferImage 事件 重置传输 关闭数据源等(同消息关闭) 通知窗口,消息已被处理

我已经用几个扫描仪对此进行了测试:

富士通 fi-5120C 每次传输页面时都会调用 TransferImage 事件。该图像会立即在我的 WPF 应用程序的图像列表中弹出。 佳能 DR-5010C 会阻止我的 WPF 应用程序,直到扫描完所有图像(直到循环结束)。 Windows 甚至说,WPF 应用程序没有响应。传输完所有图像后,仅显示少数图像,图像列表中的选择闪烁等。

我关心的不是显示问题,而是阻塞的窗口和内存问题。将传输图像的循环放入 BackgroundWorker 导致了几次崩溃,我无法调试。当然,我考虑了 WPF 的线程问题。 我也不知道怎么拆分传输循环,这样在传输完一张图片后,程序返回到消息过滤器,可以将消息标记为已处理。

【问题讨论】:

您有没有想过询问 TwaindotNet 开发人员组? http://groups.google.com/group/twaindotnet-devs?pli=1 我正在寻找一个通用的解决方案来描述消息过滤器以及与独立于 TwainDotNet 的 TWAIN 的交互。包含 TWAIN 消息的工作流就足够了。也欢迎使用其他语言,最好使用 C 或 Deplhi 等语言。 【参考方案1】:

我在 Atalasoft 工作,但我不了解 WPF,甚至不了解 DotTwain!

我可以告诉你,通常 TWAIN 扫描可以在单独的扫描线程上完成,但你必须小心。最简单的方法是在扫描线程上执行所有 TWAIN 操作 - 不要在两个线程之间混合 TWAIN 调用。

扫描线程必须有一个消息泵或者是一个“UI”线程,无论你的环境需要什么。它不仅仅是一个工作线程。

TWAIN 期望获得一个窗口句柄(老式 Win32 HWND),以用作扫描仪 UI 的父窗口。为此,我建议在扫描线程上创建一个“扫描父级”窗口。您可以选择使其可见或不可见,并在扫描作业结束时将其销毁。

如果您的扫描作业可能非常大(例如 50 页 400 DPI 颜色),您必须确保扫描过程不会填满逻辑内存或 RAM。如果你填满了逻辑内存(一个 32 位 Windows 进程获得大约 2GB 的地址空间来使用)分配将会失败。如果你填满了 RAM,消耗/处理传入图像的代码可能会开始交换,从根本上减慢,然后扫描会提前运行并填满逻辑内存。所以你需要:

    完全处理和处置扫描中的每个传入图像 线程,或 限制来自扫描线程的图像流,使其 不能超前于他们的处理/处置。

我通常发现我希望能够取消扫描线程,这需要一些耐心,因为 TWAIN 调用无法中断,而且其中一些调用很重。正如您对佳能所注意到的那样。另一方面,如果您在 TWAIN 调用中强制终止线程,则扫描程序可能需要重启电源甚至重新启动系统,并且 TWAIN 本身将阻塞,直到 TWAIN 管理器 DLL 从内存中卸载并重新加载。通常最好非常礼貌地关闭 TWAIN。

【讨论】:

以上是关于如何从文档进纸器异步扫描和传输图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 NTwain 从进纸器扫描文档

Twain 问题:是不是可以仅从进纸器扫描一份文档?

带有自动文档进纸器 (ADF) 的 C# WIA 在某些扫描仪上仅重新调整一页

使用 WIA 自动进纸器扫描仪扫描第二页失败

通过进纸器进行 WIA 扫描

如何从浏览器应用程序控制扫描仪? [关闭]